Merge pull request #4375 from pwojcikdev/logging-overhaul-10-develop

Logging overhaul
This commit is contained in:
Piotr Wójcik 2024-01-24 12:42:42 +01:00 committed by GitHub
commit b225de0ae0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
136 changed files with 2465 additions and 2381 deletions

6
.gitmodules vendored
View file

@ -31,3 +31,9 @@
[submodule "submodules/gtest-parallel"]
path = submodules/gtest-parallel
url = https://github.com/google/gtest-parallel.git
[submodule "submodules/spdlog"]
path = submodules/spdlog
url = https://github.com/gabime/spdlog.git
[submodule "submodules/fmt"]
path = submodules/fmt
url = https://github.com/fmtlib/fmt.git

View file

@ -483,10 +483,6 @@ include_directories(${BOOST_LIBRARY_INCLUDES})
add_library(Boost::stacktrace ALIAS boost_stacktrace_basic)
add_definitions(-DBOOST_STACKTRACE_GNU_SOURCE_NOT_REQUIRED)
# Workaround for GitHub builders which do not appear to have the Windows Message
# Compiler mc.exe
add_definitions(-DBOOST_LOG_WITHOUT_EVENT_LOG)
# Workaround for missing reference errata in the boost property_tree module
target_link_libraries(boost_property_tree INTERFACE Boost::any)
target_link_libraries(boost_property_tree INTERFACE Boost::format)
@ -526,7 +522,8 @@ else()
endif()
add_subdirectory(submodules/rocksdb EXCLUDE_FROM_ALL)
include_directories(cpptoml/include)
# cpptoml
include_directories(submodules/cpptoml/include)
# magic_enum
include_directories(submodules/magic_enum/include)
@ -536,6 +533,16 @@ add_subdirectory(crypto/ed25519-donna)
add_subdirectory(nano/ipc_flatbuffers_lib)
add_subdirectory(nano/ipc_flatbuffers_test)
# fmt
add_subdirectory(submodules/fmt EXCLUDE_FROM_ALL)
include_directories(submodules/fmt/include)
# spdlog
add_definitions(-DSPDLOG_FMT_EXTERNAL)
add_subdirectory(submodules/spdlog EXCLUDE_FROM_ALL)
include_directories(submodules/spdlog/include)
# miniupnp
set(UPNPC_BUILD_SHARED
OFF
CACHE BOOL "")
@ -750,6 +757,7 @@ endif()
if(NANO_GUI OR RAIBLOCKS_GUI)
install(FILES ${PROJECT_BINARY_DIR}/config-node.toml.sample DESTINATION .)
install(FILES ${PROJECT_BINARY_DIR}/config-rpc.toml.sample DESTINATION .)
install(FILES ${PROJECT_BINARY_DIR}/config-log.toml.sample DESTINATION .)
if(WIN32)
set(PLATFORM_QT_PACKAGES WinExtras)
else()
@ -760,7 +768,6 @@ if(NANO_GUI OR RAIBLOCKS_GUI)
add_library(qt nano/qt/qt.cpp nano/qt/qt.hpp)
include_directories(${CMAKE_SOURCE_DIR}/submodules)
include_directories(${CMAKE_SOURCE_DIR}/submodules/cpptoml/include)
target_link_libraries(
qt

View file

@ -64,5 +64,4 @@ target_compile_definitions(
target_link_libraries(core_test test_common)
include_directories(${CMAKE_SOURCE_DIR}/submodules)
include_directories(${CMAKE_SOURCE_DIR}/submodules/cpptoml/include)
include_directories(${CMAKE_SOURCE_DIR}/submodules/gtest/googletest/include)

View file

@ -1,6 +1,6 @@
#include <nano/crypto_lib/random_pool.hpp>
#include <nano/lib/lmdbconfig.hpp>
#include <nano/lib/logger_mt.hpp>
#include <nano/lib/logging.hpp>
#include <nano/lib/stats.hpp>
#include <nano/lib/utility.hpp>
#include <nano/lib/work.hpp>
@ -27,7 +27,7 @@ using namespace std::chrono_literals;
TEST (block_store, construction)
{
nano::logger_mt logger;
nano::logger logger;
auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants);
ASSERT_TRUE (!store->init_error ());
}
@ -102,7 +102,7 @@ TEST (block_store, sideband_serialization)
TEST (block_store, add_item)
{
nano::logger_mt logger;
nano::logger logger;
auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants);
ASSERT_TRUE (!store->init_error ());
nano::block_builder builder;
@ -133,7 +133,7 @@ TEST (block_store, add_item)
TEST (block_store, clear_successor)
{
nano::logger_mt logger;
nano::logger logger;
auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants);
ASSERT_TRUE (!store->init_error ());
nano::block_builder builder;
@ -180,7 +180,7 @@ TEST (block_store, clear_successor)
TEST (block_store, add_nonempty_block)
{
nano::logger_mt logger;
nano::logger logger;
auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants);
ASSERT_TRUE (!store->init_error ());
nano::keypair key1;
@ -207,7 +207,7 @@ TEST (block_store, add_nonempty_block)
TEST (block_store, add_two_items)
{
nano::logger_mt logger;
nano::logger logger;
auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants);
ASSERT_TRUE (!store->init_error ());
nano::keypair key1;
@ -253,7 +253,7 @@ TEST (block_store, add_two_items)
TEST (block_store, add_receive)
{
nano::logger_mt logger;
nano::logger logger;
auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants);
ASSERT_TRUE (!store->init_error ());
nano::keypair key1;
@ -289,7 +289,7 @@ TEST (block_store, add_receive)
TEST (block_store, add_pending)
{
nano::logger_mt logger;
nano::logger logger;
auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants);
ASSERT_TRUE (!store->init_error ());
nano::keypair key1;
@ -307,7 +307,7 @@ TEST (block_store, add_pending)
TEST (block_store, pending_iterator)
{
nano::logger_mt logger;
nano::logger logger;
auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants);
ASSERT_TRUE (!store->init_error ());
auto transaction (store->tx_begin_write ());
@ -332,7 +332,7 @@ TEST (block_store, pending_iterator)
*/
TEST (block_store, pending_iterator_comparison)
{
nano::logger_mt logger;
nano::logger logger;
auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants);
ASSERT_TRUE (!store->init_error ());
nano::stats stats;
@ -375,7 +375,7 @@ TEST (block_store, pending_iterator_comparison)
TEST (block_store, genesis)
{
nano::logger_mt logger;
nano::logger logger;
auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants);
ASSERT_TRUE (!store->init_error ());
nano::ledger_cache ledger_cache;
@ -403,7 +403,7 @@ TEST (block_store, genesis)
TEST (block_store, empty_accounts)
{
nano::logger_mt logger;
nano::logger logger;
auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants);
ASSERT_TRUE (!store->init_error ());
auto transaction (store->tx_begin_read ());
@ -414,7 +414,7 @@ TEST (block_store, empty_accounts)
TEST (block_store, one_block)
{
nano::logger_mt logger;
nano::logger logger;
auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants);
ASSERT_TRUE (!store->init_error ());
nano::block_builder builder;
@ -435,7 +435,7 @@ TEST (block_store, one_block)
TEST (block_store, empty_bootstrap)
{
nano::test::system system{};
nano::logger_mt logger;
nano::logger logger;
nano::unchecked_map unchecked{ system.stats, false };
size_t count = 0;
unchecked.for_each ([&count] (nano::unchecked_key const & key, nano::unchecked_info const & info) {
@ -446,7 +446,7 @@ TEST (block_store, empty_bootstrap)
TEST (block_store, unchecked_begin_search)
{
nano::logger_mt logger;
nano::logger logger;
auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants);
ASSERT_TRUE (!store->init_error ());
nano::keypair key0;
@ -471,7 +471,7 @@ TEST (block_store, unchecked_begin_search)
TEST (block_store, frontier_retrieval)
{
nano::logger_mt logger;
nano::logger logger;
auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants);
ASSERT_TRUE (!store->init_error ());
nano::account account1{};
@ -486,7 +486,7 @@ TEST (block_store, frontier_retrieval)
TEST (block_store, one_account)
{
nano::logger_mt logger;
nano::logger logger;
auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants);
ASSERT_TRUE (!store->init_error ());
nano::account account{};
@ -513,7 +513,7 @@ TEST (block_store, one_account)
TEST (block_store, two_block)
{
nano::logger_mt logger;
nano::logger logger;
auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants);
ASSERT_TRUE (!store->init_error ());
nano::block_builder builder;
@ -551,7 +551,7 @@ TEST (block_store, two_block)
TEST (block_store, two_account)
{
nano::logger_mt logger;
nano::logger logger;
auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants);
ASSERT_TRUE (!store->init_error ());
nano::account account1 (1);
@ -593,7 +593,7 @@ TEST (block_store, two_account)
TEST (block_store, latest_find)
{
nano::logger_mt logger;
nano::logger logger;
auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants);
ASSERT_TRUE (!store->init_error ());
nano::account account1 (1);
@ -627,7 +627,7 @@ TEST (mdb_block_store, supported_version_upgrades)
}
// Check that upgrading from an unsupported version is not supported
auto path (nano::unique_path () / "data.ldb");
nano::logger_mt logger;
nano::logger logger;
{
nano::store::lmdb::component store (logger, path, nano::dev::constants);
nano::stats stats;
@ -671,10 +671,11 @@ TEST (mdb_block_store, bad_path)
// Don't test this in rocksdb mode
GTEST_SKIP ();
}
nano::logger_mt logger;
nano::logger logger;
try
{
auto path = nano::unique_path ();
path /= "data.ldb";
{
std::ofstream stream (path.c_str ());
}
@ -696,14 +697,14 @@ TEST (block_store, DISABLED_already_open) // File can be shared
std::ofstream file;
file.open (path.string ().c_str ());
ASSERT_TRUE (file.is_open ());
nano::logger_mt logger;
nano::logger logger;
auto store = nano::make_store (logger, path, nano::dev::constants);
ASSERT_TRUE (store->init_error ());
}
TEST (block_store, roots)
{
nano::logger_mt logger;
nano::logger logger;
auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants);
ASSERT_TRUE (!store->init_error ());
nano::block_builder builder;
@ -745,7 +746,7 @@ TEST (block_store, roots)
TEST (block_store, pending_exists)
{
nano::logger_mt logger;
nano::logger logger;
auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants);
ASSERT_TRUE (!store->init_error ());
nano::pending_key two (2, 0);
@ -758,7 +759,7 @@ TEST (block_store, pending_exists)
TEST (block_store, latest_exists)
{
nano::logger_mt logger;
nano::logger logger;
auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants);
ASSERT_TRUE (!store->init_error ());
nano::account two (2);
@ -772,7 +773,7 @@ TEST (block_store, latest_exists)
TEST (block_store, large_iteration)
{
nano::logger_mt logger;
nano::logger logger;
auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants);
ASSERT_TRUE (!store->init_error ());
std::unordered_set<nano::account> accounts1;
@ -811,7 +812,7 @@ TEST (block_store, large_iteration)
TEST (block_store, frontier)
{
nano::logger_mt logger;
nano::logger logger;
auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants);
ASSERT_TRUE (!store->init_error ());
auto transaction (store->tx_begin_write ());
@ -826,7 +827,7 @@ TEST (block_store, frontier)
TEST (block_store, block_replace)
{
nano::logger_mt logger;
nano::logger logger;
auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants);
ASSERT_TRUE (!store->init_error ());
nano::block_builder builder;
@ -858,7 +859,7 @@ TEST (block_store, block_replace)
TEST (block_store, block_count)
{
nano::logger_mt logger;
nano::logger logger;
auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants);
ASSERT_TRUE (!store->init_error ());
{
@ -883,7 +884,7 @@ TEST (block_store, block_count)
TEST (block_store, account_count)
{
nano::logger_mt logger;
nano::logger logger;
auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants);
ASSERT_TRUE (!store->init_error ());
{
@ -899,7 +900,7 @@ TEST (block_store, account_count)
TEST (block_store, cemented_count_cache)
{
nano::logger_mt logger;
nano::logger logger;
auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants);
ASSERT_TRUE (!store->init_error ());
auto transaction (store->tx_begin_write ());
@ -910,7 +911,7 @@ TEST (block_store, cemented_count_cache)
TEST (block_store, block_random)
{
nano::logger_mt logger;
nano::logger logger;
auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants);
{
nano::ledger_cache ledger_cache;
@ -925,7 +926,7 @@ TEST (block_store, block_random)
TEST (block_store, pruned_random)
{
nano::logger_mt logger;
nano::logger logger;
auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants);
ASSERT_TRUE (!store->init_error ());
nano::block_builder builder;
@ -952,7 +953,7 @@ TEST (block_store, pruned_random)
TEST (block_store, state_block)
{
nano::logger_mt logger;
nano::logger logger;
auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants);
ASSERT_FALSE (store->init_error ());
nano::keypair key1;
@ -999,7 +1000,7 @@ TEST (mdb_block_store, sideband_height)
// Don't test this in rocksdb mode
GTEST_SKIP ();
}
nano::logger_mt logger;
nano::logger logger;
nano::keypair key1;
nano::keypair key2;
nano::keypair key3;
@ -1152,7 +1153,7 @@ TEST (mdb_block_store, sideband_height)
TEST (block_store, peers)
{
nano::logger_mt logger;
nano::logger logger;
auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants);
ASSERT_TRUE (!store->init_error ());
@ -1250,7 +1251,7 @@ TEST (block_store, endpoint_key_byte_order)
TEST (block_store, online_weight)
{
nano::logger_mt logger;
nano::logger logger;
auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants);
ASSERT_FALSE (store->init_error ());
{
@ -1285,7 +1286,7 @@ TEST (block_store, online_weight)
TEST (block_store, pruned_blocks)
{
nano::logger_mt logger;
nano::logger logger;
auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants);
ASSERT_TRUE (!store->init_error ());
@ -1372,7 +1373,7 @@ TEST (mdb_block_store, upgrade_v21_v22)
}
auto path (nano::unique_path () / "data.ldb");
nano::logger_mt logger;
nano::logger logger;
nano::stats stats;
auto const check_correct_state = [&] () {
nano::store::lmdb::component store (logger, path, nano::dev::constants);
@ -1411,7 +1412,7 @@ TEST (rocksdb_block_store, upgrade_v21_v22)
}
auto const path = nano::unique_path () / "rocksdb";
nano::logger_mt logger;
nano::logger logger;
nano::stats stats;
auto const check_correct_state = [&] () {
nano::store::rocksdb::component store (logger, path, nano::dev::constants);
@ -1471,7 +1472,7 @@ TEST (mdb_block_store, upgrade_backup)
};
{
nano::logger_mt logger;
nano::logger logger;
nano::store::lmdb::component store (logger, path, nano::dev::constants);
auto transaction (store.tx_begin_write ());
store.version.put (transaction, store.version_minimum);
@ -1479,7 +1480,7 @@ TEST (mdb_block_store, upgrade_backup)
ASSERT_EQ (get_backup_path ().string (), dir.string ());
// Now do the upgrade and confirm that backup is saved
nano::logger_mt logger;
nano::logger logger;
nano::store::lmdb::component store (logger, path, nano::dev::constants, nano::txn_tracking_config{}, std::chrono::seconds (5), nano::lmdb_config{}, true);
ASSERT_FALSE (store.init_error ());
auto transaction (store.tx_begin_read ());
@ -1496,7 +1497,7 @@ TEST (block_store, confirmation_height)
GTEST_SKIP ();
}
auto path (nano::unique_path ());
nano::logger_mt logger;
nano::logger logger;
auto store = nano::make_store (logger, path, nano::dev::constants);
nano::account account1{};
@ -1542,7 +1543,7 @@ TEST (block_store, final_vote)
GTEST_SKIP ();
}
auto path (nano::unique_path ());
nano::logger_mt logger;
nano::logger logger;
auto store = nano::make_store (logger, path, nano::dev::constants);
{
@ -1567,7 +1568,7 @@ TEST (block_store, final_vote)
TEST (block_store, incompatible_version)
{
auto path (nano::unique_path ());
nano::logger_mt logger;
nano::logger logger;
{
auto store = nano::make_store (logger, path, nano::dev::constants);
ASSERT_FALSE (store->init_error ());
@ -1590,7 +1591,7 @@ TEST (block_store, incompatible_version)
TEST (block_store, reset_renew_existing_transaction)
{
nano::logger_mt logger;
nano::logger logger;
auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants);
ASSERT_TRUE (!store->init_error ());
@ -1630,7 +1631,7 @@ TEST (block_store, reset_renew_existing_transaction)
TEST (block_store, rocksdb_force_test_env_variable)
{
nano::logger_mt logger;
nano::logger logger;
// Set environment variable
constexpr auto env_var = "TEST_USE_ROCKSDB";
@ -1660,7 +1661,7 @@ TEST (rocksdb_block_store, tombstone_count)
GTEST_SKIP ();
}
nano::test::system system;
nano::logger_mt logger;
nano::logger logger;
auto store = std::make_unique<nano::store::rocksdb::component> (logger, nano::unique_path () / "rocksdb", nano::dev::constants);
ASSERT_TRUE (!store->init_error ());
nano::block_builder builder;

View file

@ -283,7 +283,7 @@ TEST (bulk_pull, count_limit)
TEST (bootstrap_processor, DISABLED_process_none)
{
nano::test::system system (1);
auto node1 (std::make_shared<nano::node> (system.io_ctx, system.get_available_port (), nano::unique_path (), system.logging, system.work));
auto node1 (std::make_shared<nano::node> (system.io_ctx, system.get_available_port (), nano::unique_path (), system.work));
ASSERT_FALSE (node1->init_error ());
auto done (false);
node1->bootstrap_initiator.bootstrap (system.nodes[0]->network.endpoint (), false);
@ -338,7 +338,7 @@ TEST (bootstrap_processor, process_two)
ASSERT_NE (hash1, hash3);
ASSERT_NE (hash2, hash3);
auto node1 (std::make_shared<nano::node> (system.io_ctx, system.get_available_port (), nano::unique_path (), system.logging, system.work));
auto node1 (std::make_shared<nano::node> (system.io_ctx, system.get_available_port (), nano::unique_path (), system.work));
ASSERT_FALSE (node1->init_error ());
node1->bootstrap_initiator.bootstrap (node0->network.endpoint (), false);
ASSERT_NE (node1->latest (nano::dev::genesis_key.pub), node0->latest (nano::dev::genesis_key.pub));
@ -384,7 +384,7 @@ TEST (bootstrap_processor, process_state)
ASSERT_EQ (nano::process_result::progress, node0->process (*block2).code);
config.peering_port = system.get_available_port ();
auto node1 (std::make_shared<nano::node> (system.io_ctx, system.get_available_port (), nano::unique_path (), system.logging, system.work, node_flags));
auto node1 (std::make_shared<nano::node> (system.io_ctx, system.get_available_port (), nano::unique_path (), system.work, node_flags));
ASSERT_EQ (node0->latest (nano::dev::genesis_key.pub), block2->hash ());
ASSERT_NE (node1->latest (nano::dev::genesis_key.pub), block2->hash ());
node1->bootstrap_initiator.bootstrap (node0->network.endpoint (), false);
@ -415,7 +415,7 @@ TEST (bootstrap_processor, process_new)
nano::uint128_t balance2 (node1->balance (key2.pub));
ASSERT_TIMELY (10s, node1->block_confirmed (send->hash ()) && node1->block_confirmed (receive->hash ()) && node1->active.empty () && node2->active.empty ()); // All blocks should be propagated & confirmed
auto node3 (std::make_shared<nano::node> (system.io_ctx, system.get_available_port (), nano::unique_path (), system.logging, system.work));
auto node3 (std::make_shared<nano::node> (system.io_ctx, system.get_available_port (), nano::unique_path (), system.work));
ASSERT_FALSE (node3->init_error ());
node3->bootstrap_initiator.bootstrap (node1->network.endpoint (), false);
ASSERT_TIMELY_EQ (10s, node3->balance (key2.pub), balance2);
@ -468,7 +468,7 @@ TEST (bootstrap_processor, pull_diamond)
.work (*system.work.generate (send1->hash ()))
.build_shared ();
ASSERT_EQ (nano::process_result::progress, node0->process (*receive).code);
auto node1 (std::make_shared<nano::node> (system.io_ctx, system.get_available_port (), nano::unique_path (), system.logging, system.work));
auto node1 (std::make_shared<nano::node> (system.io_ctx, system.get_available_port (), nano::unique_path (), system.work));
ASSERT_FALSE (node1->init_error ());
node1->bootstrap_initiator.bootstrap (node0->network.endpoint (), false);
ASSERT_TIMELY_EQ (10s, node1->balance (nano::dev::genesis_key.pub), 100);
@ -529,7 +529,7 @@ TEST (bootstrap_processor, DISABLED_push_diamond)
config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled;
auto node0 (system.add_node (config));
nano::keypair key;
auto node1 (std::make_shared<nano::node> (system.io_ctx, system.get_available_port (), nano::unique_path (), system.logging, system.work));
auto node1 (std::make_shared<nano::node> (system.io_ctx, system.get_available_port (), nano::unique_path (), system.work));
ASSERT_FALSE (node1->init_error ());
auto wallet1 (node1->wallets.create (100));
wallet1->insert_adhoc (nano::dev::genesis_key.prv);
@ -662,7 +662,7 @@ TEST (bootstrap_processor, push_one)
config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled;
auto node0 (system.add_node (config));
nano::keypair key1;
auto node1 (std::make_shared<nano::node> (system.io_ctx, system.get_available_port (), nano::unique_path (), system.logging, system.work));
auto node1 (std::make_shared<nano::node> (system.io_ctx, system.get_available_port (), nano::unique_path (), system.work));
auto wallet (node1->wallets.create (nano::random_wallet_id ()));
ASSERT_NE (nullptr, wallet);
wallet->insert_adhoc (nano::dev::genesis_key.prv);
@ -736,7 +736,7 @@ TEST (bootstrap_processor, lazy_hash)
node0->block_processor.add (receive2);
node0->block_processor.flush ();
// Start lazy bootstrap with last block in chain known
auto node1 (std::make_shared<nano::node> (system.io_ctx, system.get_available_port (), nano::unique_path (), system.logging, system.work));
auto node1 (std::make_shared<nano::node> (system.io_ctx, system.get_available_port (), nano::unique_path (), system.work));
nano::test::establish_tcp (system, *node1, node0->network.endpoint ());
node1->bootstrap_initiator.bootstrap_lazy (receive2->hash (), true);
{
@ -810,7 +810,7 @@ TEST (bootstrap_processor, lazy_hash_bootstrap_id)
node0->block_processor.add (receive2);
node0->block_processor.flush ();
// Start lazy bootstrap with last block in chain known
auto node1 (std::make_shared<nano::node> (system.io_ctx, system.get_available_port (), nano::unique_path (), system.logging, system.work));
auto node1 (std::make_shared<nano::node> (system.io_ctx, system.get_available_port (), nano::unique_path (), system.work));
nano::test::establish_tcp (system, *node1, node0->network.endpoint ());
node1->bootstrap_initiator.bootstrap_lazy (receive2->hash (), true, "123456");
{
@ -944,7 +944,7 @@ TEST (bootstrap_processor, lazy_hash_pruning)
ASSERT_EQ (5, node1->ledger.cache.block_count);
ASSERT_EQ (5, node1->ledger.cache.cemented_count);
// Pruning action
node1->ledger_pruning (2, false, false);
node1->ledger_pruning (2, false);
ASSERT_EQ (9, node0->ledger.cache.block_count);
ASSERT_EQ (0, node0->ledger.cache.pruned_count);
ASSERT_EQ (5, node1->ledger.cache.block_count);
@ -1052,7 +1052,7 @@ TEST (bootstrap_processor, lazy_max_pull_count)
node0->block_processor.add (change3);
node0->block_processor.flush ();
// Start lazy bootstrap with last block in chain known
auto node1 (std::make_shared<nano::node> (system.io_ctx, system.get_available_port (), nano::unique_path (), system.logging, system.work));
auto node1 (std::make_shared<nano::node> (system.io_ctx, system.get_available_port (), nano::unique_path (), system.work));
nano::test::establish_tcp (system, *node1, node0->network.endpoint ());
node1->bootstrap_initiator.bootstrap_lazy (change3->hash ());
// Check processed blocks
@ -1326,7 +1326,7 @@ TEST (bootstrap_processor, lazy_pruning_missing_block)
ASSERT_EQ (5, node1->ledger.cache.block_count);
ASSERT_EQ (5, node1->ledger.cache.cemented_count);
// Pruning action
node1->ledger_pruning (2, false, false);
node1->ledger_pruning (2, false);
ASSERT_EQ (5, node1->ledger.cache.block_count);
ASSERT_EQ (1, node1->ledger.cache.pruned_count);
ASSERT_TRUE (node1->ledger.block_or_pruned_exists (send1->hash ())); // true for pruned
@ -1390,7 +1390,7 @@ TEST (bootstrap_processor, lazy_cancel)
.build_shared ();
// Start lazy bootstrap with last block in chain known
auto node1 (std::make_shared<nano::node> (system.io_ctx, system.get_available_port (), nano::unique_path (), system.logging, system.work));
auto node1 (std::make_shared<nano::node> (system.io_ctx, system.get_available_port (), nano::unique_path (), system.work));
nano::test::establish_tcp (system, *node1, node0->network.endpoint ());
node1->bootstrap_initiator.bootstrap_lazy (send1->hash (), true); // Start "confirmed" block bootstrap
{
@ -1465,7 +1465,7 @@ TEST (bootstrap_processor, wallet_lazy_frontier)
node0->block_processor.add (receive2);
node0->block_processor.flush ();
// Start wallet lazy bootstrap
auto node1 (std::make_shared<nano::node> (system.io_ctx, system.get_available_port (), nano::unique_path (), system.logging, system.work));
auto node1 (std::make_shared<nano::node> (system.io_ctx, system.get_available_port (), nano::unique_path (), system.work));
nano::test::establish_tcp (system, *node1, node0->network.endpoint ());
auto wallet (node1->wallets.create (nano::random_wallet_id ()));
ASSERT_NE (nullptr, wallet);
@ -1911,14 +1911,14 @@ TEST (frontier_req, confirmed_frontier)
TEST (bulk, genesis)
{
nano::test::system system;
nano::node_config config (system.get_available_port (), system.logging);
nano::node_config config (system.get_available_port ());
config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled;
nano::node_flags node_flags;
node_flags.disable_bootstrap_bulk_push_client = true;
node_flags.disable_lazy_bootstrap = true;
auto node1 = system.add_node (config, node_flags);
system.wallet (0)->insert_adhoc (nano::dev::genesis_key.prv);
auto node2 (std::make_shared<nano::node> (system.io_ctx, system.get_available_port (), nano::unique_path (), system.logging, system.work));
auto node2 (std::make_shared<nano::node> (system.io_ctx, system.get_available_port (), nano::unique_path (), system.work));
ASSERT_FALSE (node2->init_error ());
nano::block_hash latest1 (node1->latest (nano::dev::genesis_key.pub));
nano::block_hash latest2 (node2->latest (nano::dev::genesis_key.pub));
@ -1938,14 +1938,14 @@ TEST (bulk, genesis)
TEST (bulk, offline_send)
{
nano::test::system system;
nano::node_config config (system.get_available_port (), system.logging);
nano::node_config config (system.get_available_port ());
config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled;
nano::node_flags node_flags;
node_flags.disable_bootstrap_bulk_push_client = true;
node_flags.disable_lazy_bootstrap = true;
auto node1 = system.add_node (config, node_flags);
system.wallet (0)->insert_adhoc (nano::dev::genesis_key.prv);
auto node2 (std::make_shared<nano::node> (system.io_ctx, system.get_available_port (), nano::unique_path (), system.logging, system.work));
auto node2 (std::make_shared<nano::node> (system.io_ctx, system.get_available_port (), nano::unique_path (), system.work));
ASSERT_FALSE (node2->init_error ());
node2->start ();
system.nodes.push_back (node2);
@ -1980,7 +1980,7 @@ TEST (bulk, offline_send)
TEST (bulk, DISABLED_genesis_pruning)
{
nano::test::system system;
nano::node_config config (system.get_available_port (), system.logging);
nano::node_config config (system.get_available_port ());
config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled;
config.enable_voting = false; // Remove after allowing pruned voting
nano::node_flags node_flags;
@ -1991,7 +1991,7 @@ TEST (bulk, DISABLED_genesis_pruning)
auto node1 = system.add_node (config, node_flags);
system.wallet (0)->insert_adhoc (nano::dev::genesis_key.prv);
node_flags.enable_pruning = false;
auto node2 (std::make_shared<nano::node> (system.io_ctx, system.get_available_port (), nano::unique_path (), system.logging, system.work, node_flags));
auto node2 (std::make_shared<nano::node> (system.io_ctx, system.get_available_port (), nano::unique_path (), system.work, node_flags));
ASSERT_FALSE (node2->init_error ());
nano::block_hash latest1 (node1->latest (nano::dev::genesis_key.pub));
nano::block_hash latest2 (node2->latest (nano::dev::genesis_key.pub));
@ -2031,7 +2031,7 @@ TEST (bulk, DISABLED_genesis_pruning)
election->force_confirm ();
}
ASSERT_TIMELY (2s, node1->active.empty () && node1->block_confirmed (send3->hash ()));
node1->ledger_pruning (2, false, false);
node1->ledger_pruning (2, false);
ASSERT_EQ (2, node1->ledger.cache.pruned_count);
ASSERT_EQ (4, node1->ledger.cache.block_count);
ASSERT_TRUE (node1->ledger.block_or_pruned_exists (send1->hash ())); // true for pruned

View file

@ -1,3 +1,4 @@
#include <nano/lib/logging.hpp>
#include <nano/lib/stats.hpp>
#include <nano/lib/tomlconfig.hpp>
#include <nano/node/bootstrap_ascending/service.hpp>
@ -24,7 +25,7 @@ nano::block_hash random_hash ()
TEST (account_sets, construction)
{
nano::stats stats;
nano::logger_mt logger;
nano::logger logger;
auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants);
ASSERT_FALSE (store->init_error ());
nano::bootstrap_ascending::account_sets sets{ stats };
@ -34,7 +35,7 @@ TEST (account_sets, empty_blocked)
{
nano::account account{ 1 };
nano::stats stats;
nano::logger_mt logger;
nano::logger logger;
auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants);
ASSERT_FALSE (store->init_error ());
nano::bootstrap_ascending::account_sets sets{ stats };
@ -45,7 +46,7 @@ TEST (account_sets, block)
{
nano::account account{ 1 };
nano::stats stats;
nano::logger_mt logger;
nano::logger logger;
auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants);
ASSERT_FALSE (store->init_error ());
nano::bootstrap_ascending::account_sets sets{ stats };
@ -57,7 +58,7 @@ TEST (account_sets, unblock)
{
nano::account account{ 1 };
nano::stats stats;
nano::logger_mt logger;
nano::logger logger;
auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants);
ASSERT_FALSE (store->init_error ());
nano::bootstrap_ascending::account_sets sets{ stats };
@ -71,7 +72,7 @@ TEST (account_sets, priority_base)
{
nano::account account{ 1 };
nano::stats stats;
nano::logger_mt logger;
nano::logger logger;
auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants);
ASSERT_FALSE (store->init_error ());
nano::bootstrap_ascending::account_sets sets{ stats };
@ -82,7 +83,7 @@ TEST (account_sets, priority_blocked)
{
nano::account account{ 1 };
nano::stats stats;
nano::logger_mt logger;
nano::logger logger;
auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants);
ASSERT_FALSE (store->init_error ());
nano::bootstrap_ascending::account_sets sets{ stats };
@ -95,7 +96,7 @@ TEST (account_sets, priority_unblock_keep)
{
nano::account account{ 1 };
nano::stats stats;
nano::logger_mt logger;
nano::logger logger;
auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants);
ASSERT_FALSE (store->init_error ());
nano::bootstrap_ascending::account_sets sets{ stats };
@ -113,7 +114,7 @@ TEST (account_sets, priority_up_down)
{
nano::account account{ 1 };
nano::stats stats;
nano::logger_mt logger;
nano::logger logger;
auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants);
ASSERT_FALSE (store->init_error ());
nano::bootstrap_ascending::account_sets sets{ stats };
@ -128,7 +129,7 @@ TEST (account_sets, priority_down_sat)
{
nano::account account{ 1 };
nano::stats stats;
nano::logger_mt logger;
nano::logger logger;
auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants);
ASSERT_FALSE (store->init_error ());
nano::bootstrap_ascending::account_sets sets{ stats };
@ -141,7 +142,7 @@ TEST (account_sets, saturate_priority)
{
nano::account account{ 1 };
nano::stats stats;
nano::logger_mt logger;
nano::logger logger;
auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants);
ASSERT_FALSE (store->init_error ());
nano::bootstrap_ascending::account_sets sets{ stats };

View file

@ -1,3 +1,4 @@
#include <nano/lib/logging.hpp>
#include <nano/node/election.hpp>
#include <nano/node/make_store.hpp>
#include <nano/test_common/system.hpp>
@ -1157,8 +1158,7 @@ TEST (confirmation_heightDeathTest, rollback_added_block)
// valgrind can be noisy with death tests
if (!nano::running_within_valgrind ())
{
nano::logger_mt logger;
nano::logging logging;
nano::logger logger;
auto path (nano::unique_path ());
auto store = nano::make_store (logger, path, nano::dev::constants);
ASSERT_TRUE (!store->init_error ());
@ -1184,13 +1184,13 @@ TEST (confirmation_heightDeathTest, rollback_added_block)
uint64_t batch_write_size = 2048;
std::atomic<bool> stopped{ false };
nano::confirmation_height_unbounded unbounded_processor (
ledger, write_database_queue, 10ms, logging, logger, stopped, batch_write_size, [] (auto const &) {}, [] (auto const &) {}, [] () { return 0; });
ledger, write_database_queue, 10ms, logger, stopped, batch_write_size, [] (auto const &) {}, [] (auto const &) {}, [] () { return 0; });
// Processing a block which doesn't exist should bail
ASSERT_DEATH_IF_SUPPORTED (unbounded_processor.process (send), "");
nano::confirmation_height_bounded bounded_processor (
ledger, write_database_queue, 10ms, logging, logger, stopped, batch_write_size, [] (auto const &) {}, [] (auto const &) {}, [] () { return 0; });
ledger, write_database_queue, 10ms, logger, stopped, batch_write_size, [] (auto const &) {}, [] (auto const &) {}, [] () { return 0; });
// Processing a block which doesn't exist should bail
ASSERT_DEATH_IF_SUPPORTED (bounded_processor.process (send), "");
}
@ -1249,8 +1249,7 @@ TEST (confirmation_heightDeathTest, modified_chain)
// valgrind can be noisy with death tests
if (!nano::running_within_valgrind ())
{
nano::logging logging;
nano::logger_mt logger;
nano::logger logger;
auto path (nano::unique_path ());
auto store = nano::make_store (logger, path, nano::dev::constants);
ASSERT_TRUE (!store->init_error ());
@ -1277,7 +1276,7 @@ TEST (confirmation_heightDeathTest, modified_chain)
uint64_t batch_write_size = 2048;
std::atomic<bool> stopped{ false };
nano::confirmation_height_bounded bounded_processor (
ledger, write_database_queue, 10ms, logging, logger, stopped, batch_write_size, [] (auto const &) {}, [] (auto const &) {}, [] () { return 0; });
ledger, write_database_queue, 10ms, logger, stopped, batch_write_size, [] (auto const &) {}, [] (auto const &) {}, [] () { return 0; });
{
// This reads the blocks in the account, but prevents any writes from occuring yet
@ -1296,7 +1295,7 @@ TEST (confirmation_heightDeathTest, modified_chain)
store->confirmation_height.put (store->tx_begin_write (), nano::dev::genesis->account (), { 1, nano::dev::genesis->hash () });
nano::confirmation_height_unbounded unbounded_processor (
ledger, write_database_queue, 10ms, logging, logger, stopped, batch_write_size, [] (auto const &) {}, [] (auto const &) {}, [] () { return 0; });
ledger, write_database_queue, 10ms, logger, stopped, batch_write_size, [] (auto const &) {}, [] (auto const &) {}, [] () { return 0; });
{
// This reads the blocks in the account, but prevents any writes from occuring yet
@ -1327,8 +1326,7 @@ TEST (confirmation_heightDeathTest, modified_chain_account_removed)
// valgrind can be noisy with death tests
if (!nano::running_within_valgrind ())
{
nano::logging logging;
nano::logger_mt logger;
nano::logger logger;
auto path (nano::unique_path ());
auto store = nano::make_store (logger, path, nano::dev::constants);
ASSERT_TRUE (!store->init_error ());
@ -1366,7 +1364,7 @@ TEST (confirmation_heightDeathTest, modified_chain_account_removed)
uint64_t batch_write_size = 2048;
std::atomic<bool> stopped{ false };
nano::confirmation_height_unbounded unbounded_processor (
ledger, write_database_queue, 10ms, logging, logger, stopped, batch_write_size, [] (auto const &) {}, [] (auto const &) {}, [] () { return 0; });
ledger, write_database_queue, 10ms, logger, stopped, batch_write_size, [] (auto const &) {}, [] (auto const &) {}, [] () { return 0; });
{
// This reads the blocks in the account, but prevents any writes from occuring yet
@ -1386,7 +1384,7 @@ TEST (confirmation_heightDeathTest, modified_chain_account_removed)
store->confirmation_height.put (store->tx_begin_write (), nano::dev::genesis->account (), { 1, nano::dev::genesis->hash () });
nano::confirmation_height_bounded bounded_processor (
ledger, write_database_queue, 10ms, logging, logger, stopped, batch_write_size, [] (auto const &) {}, [] (auto const &) {}, [] () { return 0; });
ledger, write_database_queue, 10ms, logger, stopped, batch_write_size, [] (auto const &) {}, [] (auto const &) {}, [] () { return 0; });
{
// This reads the blocks in the account, but prevents any writes from occuring yet
@ -2039,7 +2037,7 @@ TEST (confirmation_height, unbounded_block_cache_iteration)
// Don't test this in rocksdb mode
GTEST_SKIP ();
}
nano::logger_mt logger;
nano::logger logger;
auto path (nano::unique_path ());
auto store = nano::make_store (logger, path, nano::dev::constants);
ASSERT_TRUE (!store->init_error ());
@ -2048,7 +2046,6 @@ TEST (confirmation_height, unbounded_block_cache_iteration)
nano::write_database_queue write_database_queue (false);
boost::latch initialized_latch{ 0 };
nano::work_pool pool{ nano::dev::network_params.network, std::numeric_limits<unsigned>::max () };
nano::logging logging;
nano::keypair key1;
nano::block_builder builder;
auto send = builder
@ -2074,7 +2071,7 @@ TEST (confirmation_height, unbounded_block_cache_iteration)
ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, *send1).code);
}
nano::confirmation_height_processor confirmation_height_processor (ledger, write_database_queue, 10ms, logging, logger, initialized_latch, nano::confirmation_height_mode::unbounded);
nano::confirmation_height_processor confirmation_height_processor (ledger, write_database_queue, 10ms, logger, initialized_latch, nano::confirmation_height_mode::unbounded);
nano::timer<> timer;
timer.start ();
{
@ -2103,8 +2100,7 @@ TEST (confirmation_height, unbounded_block_cache_iteration)
TEST (confirmation_height, pruned_source)
{
nano::logger_mt logger;
nano::logging logging;
nano::logger logger;
auto path (nano::unique_path ());
auto store = nano::make_store (logger, path, nano::dev::constants);
ASSERT_TRUE (!store->init_error ());
@ -2178,7 +2174,7 @@ TEST (confirmation_height, pruned_source)
std::atomic<bool> stopped{ false };
bool first_time{ true };
nano::confirmation_height_bounded bounded_processor (
ledger, write_database_queue, 10ms, logging, logger, stopped, batch_write_size, [&] (auto const & cemented_blocks_a) {
ledger, write_database_queue, 10ms, logger, stopped, batch_write_size, [&] (auto const & cemented_blocks_a) {
if (first_time)
{
// Prune the send

View file

@ -1,7 +1,7 @@
#include "gtest/gtest.h"
#include <nano/lib/logging.hpp>
#include <nano/node/common.hpp>
#include <nano/node/logging.hpp>
#include <nano/secure/utility.hpp>
#include <boost/filesystem/path.hpp>
@ -19,13 +19,10 @@ void force_nano_dev_network ();
GTEST_API_ int main (int argc, char ** argv)
{
printf ("Running main() from core_test_main.cc\n");
nano::logger::initialize_for_tests (nano::log_config::tests_default ());
nano::set_file_descriptor_limit (OPEN_FILE_DESCRIPTORS_LIMIT);
nano::force_nano_dev_network ();
nano::node_singleton_memory_pool_purge_guard memory_pool_cleanup_guard;
// Setting up logging so that there aren't any piped to standard output.
nano::logging logging;
logging.init (nano::unique_path ());
testing::InitGoogleTest (&argc, argv);
auto res = RUN_ALL_TESTS ();
nano::test::cleanup_dev_directories_on_exit ();

View file

@ -1,3 +1,4 @@
#include <nano/lib/logging.hpp>
#include <nano/lib/stats.hpp>
#include <nano/lib/threading.hpp>
#include <nano/node/election.hpp>
@ -817,7 +818,7 @@ TEST (ledger, representation)
TEST (ledger, double_open)
{
nano::logger_mt logger;
nano::logger logger;
auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants);
ASSERT_TRUE (!store->init_error ());
nano::stats stats;
@ -4161,7 +4162,7 @@ TEST (ledger, block_hash_account_conflict)
TEST (ledger, could_fit)
{
nano::logger_mt logger;
nano::logger logger;
auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants);
ASSERT_TRUE (!store->init_error ());
nano::stats stats;
@ -4799,7 +4800,7 @@ TEST (ledger, dependents_confirmed)
TEST (ledger, dependents_confirmed_pruning)
{
nano::logger_mt logger;
nano::logger logger;
auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants);
ASSERT_FALSE (store->init_error ());
nano::stats stats;
@ -4989,7 +4990,7 @@ TEST (ledger, cache)
TEST (ledger, pruning_action)
{
nano::logger_mt logger;
nano::logger logger;
auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants);
ASSERT_TRUE (!store->init_error ());
nano::stats stats;
@ -5073,7 +5074,7 @@ TEST (ledger, pruning_action)
TEST (ledger, pruning_large_chain)
{
nano::logger_mt logger;
nano::logger logger;
auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants);
ASSERT_TRUE (!store->init_error ());
nano::stats stats;
@ -5128,7 +5129,7 @@ TEST (ledger, pruning_large_chain)
TEST (ledger, pruning_source_rollback)
{
nano::logger_mt logger;
nano::logger logger;
auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants);
ASSERT_TRUE (!store->init_error ());
nano::stats stats;
@ -5216,7 +5217,7 @@ TEST (ledger, pruning_source_rollback)
TEST (ledger, pruning_source_rollback_legacy)
{
nano::logger_mt logger;
nano::logger logger;
auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants);
ASSERT_TRUE (!store->init_error ());
nano::stats stats;
@ -5329,7 +5330,7 @@ TEST (ledger, pruning_source_rollback_legacy)
TEST (ledger, pruning_process_error)
{
nano::logger_mt logger;
nano::logger logger;
auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants);
ASSERT_TRUE (!store->init_error ());
nano::stats stats;
@ -5376,7 +5377,7 @@ TEST (ledger, pruning_process_error)
TEST (ledger, pruning_legacy_blocks)
{
nano::logger_mt logger;
nano::logger logger;
auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants);
ASSERT_TRUE (!store->init_error ());
nano::stats stats;
@ -5462,7 +5463,7 @@ TEST (ledger, pruning_legacy_blocks)
TEST (ledger, pruning_safe_functions)
{
nano::logger_mt logger;
nano::logger logger;
auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants);
ASSERT_TRUE (!store->init_error ());
nano::stats stats;
@ -5523,7 +5524,7 @@ TEST (ledger, pruning_safe_functions)
TEST (ledger, hash_root_random)
{
nano::logger_mt logger;
nano::logger logger;
auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants);
ASSERT_TRUE (!store->init_error ());
nano::stats stats;
@ -5587,7 +5588,7 @@ TEST (ledger, migrate_lmdb_to_rocksdb)
{
nano::test::system system{};
auto path = nano::unique_path ();
nano::logger_mt logger{};
nano::logger logger;
boost::asio::ip::address_v6 address (boost::asio::ip::make_address_v6 ("::ffff:127.0.0.1"));
uint16_t port = 100;
nano::store::lmdb::component store{ logger, path / "data.ldb", nano::dev::constants };

View file

@ -1,5 +1,4 @@
#include <nano/lib/logger_mt.hpp>
#include <nano/node/logging.hpp>
#include <nano/secure/utility.hpp>
#include <nano/test_common/testutil.hpp>
@ -11,98 +10,7 @@
using namespace std::chrono_literals;
TEST (logger, changing_time_interval)
TEST (logger, basic)
{
auto path1 (nano::unique_path ());
nano::logging logging;
logging.init (path1);
logging.min_time_between_log_output = 0ms;
nano::logger_mt my_logger (logging.min_time_between_log_output);
auto error (my_logger.try_log ("logger.changing_time_interval1"));
ASSERT_FALSE (error);
my_logger.min_log_delta = 20s;
error = my_logger.try_log ("logger, changing_time_interval2");
ASSERT_TRUE (error);
}
TEST (logger, try_log)
{
auto path1 (nano::unique_path ());
std::stringstream ss;
nano::test::boost_log_cerr_redirect redirect_cerr (ss.rdbuf ());
nano::logger_mt my_logger (100ms);
auto output1 = "logger.try_log1";
auto error (my_logger.try_log (output1));
ASSERT_FALSE (error);
auto output2 = "logger.try_log2";
error = my_logger.try_log (output2);
ASSERT_TRUE (error); // Fails as it is occuring too soon
// Sleep for a bit and then confirm
std::this_thread::sleep_for (100ms);
error = my_logger.try_log (output2);
ASSERT_FALSE (error);
std::string str;
std::getline (ss, str, '\n');
ASSERT_STREQ (str.c_str (), output1);
std::getline (ss, str, '\n');
ASSERT_STREQ (str.c_str (), output2);
}
TEST (logger, always_log)
{
auto path1 (nano::unique_path ());
std::stringstream ss;
nano::test::boost_log_cerr_redirect redirect_cerr (ss.rdbuf ());
nano::logger_mt my_logger (20s); // Make time interval effectively unreachable
auto output1 = "logger.always_log1";
auto error (my_logger.try_log (output1));
ASSERT_FALSE (error);
// Time is too soon after, so it won't be logged
auto output2 = "logger.always_log2";
error = my_logger.try_log (output2);
ASSERT_TRUE (error);
// Force it to be logged
my_logger.always_log (output2);
std::string str;
std::getline (ss, str, '\n');
ASSERT_STREQ (str.c_str (), output1);
std::getline (ss, str, '\n');
ASSERT_STREQ (str.c_str (), output2);
}
TEST (logger, stable_filename)
{
auto path (nano::unique_path ());
nano::logging logging;
// Releasing allows setting up logging again
logging.release_file_sink ();
logging.stable_log_filename = true;
logging.init (path);
nano::logger_mt logger (logging.min_time_between_log_output);
logger.always_log ("stable1");
auto log_file = path / "log" / "node.log";
#if BOOST_VERSION >= 107000
EXPECT_TRUE (std::filesystem::exists (log_file));
// Try opening it again
logging.release_file_sink ();
logging.init (path);
logger.always_log ("stable2");
#else
// When using Boost < 1.70 , behavior is reverted to not using the stable filename
EXPECT_FALSE (std::filesystem::exists (log_file));
#endif
// Reset the logger
logging.release_file_sink ();
nano::logging ().init (path);
// TODO
}

View file

@ -362,22 +362,6 @@ TEST (message, confirm_req_hash_batch_serialization_v2)
ASSERT_TRUE (header.confirm_is_v2 ());
}
// this unit test checks that conversion of message_header to string works as expected
TEST (message, message_header_to_string)
{
// calculate expected string
int maxver = nano::dev::network_params.network.protocol_version;
int minver = nano::dev::network_params.network.protocol_version_min;
std::stringstream ss;
ss << "NetID: 5241(dev), VerMaxUsingMin: " << maxver << "/" << maxver << "/" << minver << ", MsgType: 2(keepalive), Extensions: 0000";
auto expected_str = ss.str ();
// check expected vs real
nano::keepalive keepalive_msg{ nano::dev::network_params.network };
std::string header_string = keepalive_msg.header.to_string ();
ASSERT_EQ (expected_str, header_string);
}
/**
* Test that a confirm_ack can encode an empty hash set
*/

View file

@ -58,7 +58,7 @@ TEST (network, construction_with_specified_port)
{
nano::test::system system{};
auto const port = system.get_available_port (/* do not allow 0 port */ false);
auto const node = system.add_node (nano::node_config{ port, system.logging });
auto const node = system.add_node (nano::node_config{ port });
EXPECT_EQ (port, node->network.port);
EXPECT_EQ (port, node->network.endpoint ().port ());
EXPECT_EQ (port, node->tcp_listener->endpoint ().port ());
@ -79,7 +79,7 @@ TEST (network, send_node_id_handshake_tcp)
nano::test::system system (1);
auto node0 (system.nodes[0]);
ASSERT_EQ (0, node0->network.size ());
auto node1 (std::make_shared<nano::node> (system.io_ctx, system.get_available_port (), nano::unique_path (), system.logging, system.work));
auto node1 (std::make_shared<nano::node> (system.io_ctx, system.get_available_port (), nano::unique_path (), system.work));
node1->start ();
system.nodes.push_back (node1);
auto initial (node0->stats.count (nano::stat::type::message, nano::stat::detail::node_id_handshake, nano::stat::dir::in));
@ -157,7 +157,7 @@ TEST (network, multi_keepalive)
nano::test::system system (1);
auto node0 = system.nodes[0];
ASSERT_EQ (0, node0->network.size ());
auto node1 (std::make_shared<nano::node> (system.io_ctx, system.get_available_port (), nano::unique_path (), system.logging, system.work));
auto node1 (std::make_shared<nano::node> (system.io_ctx, system.get_available_port (), nano::unique_path (), system.work));
ASSERT_FALSE (node1->init_error ());
node1->start ();
system.nodes.push_back (node1);
@ -165,7 +165,7 @@ TEST (network, multi_keepalive)
ASSERT_EQ (0, node0->network.size ());
node1->network.tcp_channels.start_tcp (node0->network.endpoint ());
ASSERT_TIMELY (10s, node0->network.size () == 1 && node0->stats.count (nano::stat::type::message, nano::stat::detail::keepalive) >= 1);
auto node2 (std::make_shared<nano::node> (system.io_ctx, system.get_available_port (), nano::unique_path (), system.logging, system.work));
auto node2 (std::make_shared<nano::node> (system.io_ctx, system.get_available_port (), nano::unique_path (), system.work));
ASSERT_FALSE (node2->init_error ());
node2->start ();
system.nodes.push_back (node2);
@ -749,7 +749,7 @@ TEST (network, peer_max_tcp_attempts)
auto node = system.add_node (node_flags);
for (auto i (0); i < node->network_params.network.max_peers_per_ip; ++i)
{
auto node2 (std::make_shared<nano::node> (system.io_ctx, system.get_available_port (), nano::unique_path (), system.logging, system.work, node_flags));
auto node2 (std::make_shared<nano::node> (system.io_ctx, system.get_available_port (), nano::unique_path (), system.work, node_flags));
node2->start ();
system.nodes.push_back (node2);
// Start TCP attempt
@ -826,7 +826,7 @@ TEST (network, duplicate_revert_publish)
nano::uint128_t digest;
ASSERT_FALSE (node.network.publish_filter.apply (bytes.data (), bytes.size (), &digest));
ASSERT_TRUE (node.network.publish_filter.apply (bytes.data (), bytes.size ()));
auto other_node (std::make_shared<nano::node> (system.io_ctx, system.get_available_port (), nano::unique_path (), system.logging, system.work));
auto other_node (std::make_shared<nano::node> (system.io_ctx, system.get_available_port (), nano::unique_path (), system.work));
other_node->start ();
system.nodes.push_back (other_node);
auto channel = nano::test::establish_tcp (system, *other_node, node.network.endpoint ());
@ -957,7 +957,7 @@ TEST (network, tcp_no_connect_excluded_peers)
nano::test::system system (1);
auto node0 (system.nodes[0]);
ASSERT_EQ (0, node0->network.size ());
auto node1 (std::make_shared<nano::node> (system.io_ctx, system.get_available_port (), nano::unique_path (), system.logging, system.work));
auto node1 (std::make_shared<nano::node> (system.io_ctx, system.get_available_port (), nano::unique_path (), system.work));
node1->start ();
system.nodes.push_back (node1);
auto endpoint1_tcp (nano::transport::map_endpoint_to_tcp (node1->network.endpoint ()));
@ -1058,7 +1058,7 @@ TEST (network, cleanup_purge)
nano::test::system system (1);
auto & node1 (*system.nodes[0]);
auto node2 (std::make_shared<nano::node> (system.io_ctx, system.get_available_port (), nano::unique_path (), system.logging, system.work));
auto node2 (std::make_shared<nano::node> (system.io_ctx, system.get_available_port (), nano::unique_path (), system.work));
node2->start ();
system.nodes.push_back (node2);

View file

@ -1,4 +1,5 @@
#include <nano/lib/config.hpp>
#include <nano/lib/logging.hpp>
#include <nano/node/election.hpp>
#include <nano/node/make_store.hpp>
#include <nano/node/scheduler/component.hpp>
@ -67,10 +68,8 @@ TEST (node, block_store_path_failure)
nano::test::system system;
auto service (std::make_shared<boost::asio::io_context> ());
auto path (nano::unique_path ());
nano::logging logging;
logging.init (path);
nano::work_pool pool{ nano::dev::network_params.network, std::numeric_limits<unsigned>::max () };
auto node (std::make_shared<nano::node> (*service, system.get_available_port (), path, logging, pool));
auto node (std::make_shared<nano::node> (*service, system.get_available_port (), path, pool));
ASSERT_TRUE (node->wallets.items.empty ());
node->stop ();
}
@ -100,7 +99,6 @@ TEST (node, password_fanout)
auto path (nano::unique_path ());
nano::node_config config;
config.peering_port = system.get_available_port ();
config.logging.init (path);
nano::work_pool pool{ nano::dev::network_params.network, std::numeric_limits<unsigned>::max () };
config.password_fanout = 10;
nano::node node (io_ctx, path, config, pool);
@ -266,7 +264,7 @@ TEST (node, node_receive_quorum)
TEST (node, auto_bootstrap)
{
nano::test::system system;
nano::node_config config (system.get_available_port (), system.logging);
nano::node_config config (system.get_available_port ());
config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled;
nano::node_flags node_flags;
node_flags.disable_bootstrap_bulk_push_client = true;
@ -278,7 +276,7 @@ TEST (node, auto_bootstrap)
auto send1 (system.wallet (0)->send_action (nano::dev::genesis_key.pub, key2.pub, node0->config.receive_minimum.number ()));
ASSERT_NE (nullptr, send1);
ASSERT_TIMELY_EQ (10s, node0->balance (key2.pub), node0->config.receive_minimum.number ());
auto node1 (std::make_shared<nano::node> (system.io_ctx, system.get_available_port (), nano::unique_path (), system.logging, system.work, node_flags));
auto node1 (std::make_shared<nano::node> (system.io_ctx, system.get_available_port (), nano::unique_path (), system.work, node_flags));
ASSERT_FALSE (node1->init_error ());
node1->start ();
system.nodes.push_back (node1);
@ -298,7 +296,7 @@ TEST (node, auto_bootstrap)
TEST (node, auto_bootstrap_reverse)
{
nano::test::system system;
nano::node_config config (system.get_available_port (), system.logging);
nano::node_config config (system.get_available_port ());
config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled;
nano::node_flags node_flags;
node_flags.disable_bootstrap_bulk_push_client = true;
@ -307,7 +305,7 @@ TEST (node, auto_bootstrap_reverse)
nano::keypair key2;
system.wallet (0)->insert_adhoc (nano::dev::genesis_key.prv);
system.wallet (0)->insert_adhoc (key2.prv);
auto node1 (std::make_shared<nano::node> (system.io_ctx, system.get_available_port (), nano::unique_path (), system.logging, system.work, node_flags));
auto node1 (std::make_shared<nano::node> (system.io_ctx, system.get_available_port (), nano::unique_path (), system.work, node_flags));
ASSERT_FALSE (node1->init_error ());
ASSERT_NE (nullptr, system.wallet (0)->send_action (nano::dev::genesis_key.pub, key2.pub, node0->config.receive_minimum.number ()));
node1->start ();
@ -319,14 +317,14 @@ TEST (node, auto_bootstrap_reverse)
TEST (node, auto_bootstrap_age)
{
nano::test::system system;
nano::node_config config (system.get_available_port (), system.logging);
nano::node_config config (system.get_available_port ());
config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled;
nano::node_flags node_flags;
node_flags.disable_bootstrap_bulk_push_client = true;
node_flags.disable_lazy_bootstrap = true;
node_flags.bootstrap_interval = 1;
auto node0 = system.add_node (config, node_flags);
auto node1 (std::make_shared<nano::node> (system.io_ctx, system.get_available_port (), nano::unique_path (), system.logging, system.work, node_flags));
auto node1 (std::make_shared<nano::node> (system.io_ctx, system.get_available_port (), nano::unique_path (), system.work, node_flags));
ASSERT_FALSE (node1->init_error ());
node1->start ();
system.nodes.push_back (node1);
@ -416,7 +414,7 @@ TEST (node, search_receivable_multiple)
TEST (node, search_receivable_confirmed)
{
nano::test::system system;
nano::node_config node_config (system.get_available_port (), system.logging);
nano::node_config node_config (system.get_available_port ());
node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled;
auto node = system.add_node (node_config);
nano::keypair key2;
@ -450,12 +448,12 @@ TEST (node, search_receivable_confirmed)
TEST (node, search_receivable_pruned)
{
nano::test::system system;
nano::node_config node_config (system.get_available_port (), system.logging);
nano::node_config node_config (system.get_available_port ());
node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled;
auto node1 = system.add_node (node_config);
nano::node_flags node_flags;
node_flags.enable_pruning = true;
nano::node_config config (system.get_available_port (), system.logging);
nano::node_config config (system.get_available_port ());
config.enable_voting = false; // Remove after allowing pruned voting
auto node2 = system.add_node (config, node_flags);
nano::keypair key2;
@ -549,9 +547,7 @@ TEST (node, confirm_locked)
TEST (node_config, random_rep)
{
auto path (nano::unique_path ());
nano::logging logging1;
logging1.init (path);
nano::node_config config1 (100, logging1);
nano::node_config config1 (100);
auto rep (config1.random_representative ());
ASSERT_NE (config1.preconfigured_representatives.end (), std::find (config1.preconfigured_representatives.begin (), config1.preconfigured_representatives.end (), rep));
}
@ -766,7 +762,7 @@ TEST (node, fork_multi_flip)
auto type = nano::transport::transport_type::tcp;
nano::test::system system;
nano::node_flags node_flags;
nano::node_config node_config (system.get_available_port (), system.logging);
nano::node_config node_config (system.get_available_port ());
node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled;
auto & node1 (*system.add_node (node_config, node_flags, type));
node_config.peering_port = system.get_available_port ();
@ -839,13 +835,13 @@ TEST (node, fork_bootstrap_flip)
nano::test::system system;
nano::test::system system0;
nano::test::system system1;
nano::node_config config0{ system.get_available_port (), system0.logging };
nano::node_config config0{ system.get_available_port () };
config0.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled;
nano::node_flags node_flags;
node_flags.disable_bootstrap_bulk_push_client = true;
node_flags.disable_lazy_bootstrap = true;
auto & node1 = *system0.add_node (config0, node_flags);
nano::node_config config1 (system.get_available_port (), system1.logging);
nano::node_config config1 (system.get_available_port ());
auto & node2 = *system1.add_node (config1, node_flags);
system0.wallet (0)->insert_adhoc (nano::dev::genesis_key.prv);
nano::block_hash latest = node1.latest (nano::dev::genesis_key.pub);
@ -1251,7 +1247,7 @@ TEST (node, DISABLED_broadcast_elected)
auto type = nano::transport::transport_type::tcp;
nano::node_flags node_flags;
nano::test::system system;
nano::node_config node_config (system.get_available_port (), system.logging);
nano::node_config node_config (system.get_available_port ());
node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled;
auto node0 = system.add_node (node_config, node_flags, type);
node_config.peering_port = system.get_available_port ();
@ -1377,7 +1373,7 @@ TEST (node, DISABLED_broadcast_elected)
TEST (node, rep_self_vote)
{
nano::test::system system;
nano::node_config node_config (system.get_available_port (), system.logging);
nano::node_config node_config (system.get_available_port ());
node_config.online_weight_minimum = std::numeric_limits<nano::uint128_t>::max ();
node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled;
auto node0 = system.add_node (node_config);
@ -1475,10 +1471,10 @@ TEST (node, DISABLED_bootstrap_bulk_push)
nano::test::system system;
nano::test::system system0;
nano::test::system system1;
nano::node_config config0 (system.get_available_port (), system0.logging);
nano::node_config config0 (system.get_available_port ());
config0.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled;
auto node0 (system0.add_node (config0));
nano::node_config config1 (system.get_available_port (), system1.logging);
nano::node_config config1 (system.get_available_port ());
config1.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled;
auto node1 (system1.add_node (config1));
nano::keypair key0;
@ -1515,7 +1511,7 @@ TEST (node, DISABLED_bootstrap_bulk_push)
TEST (node, bootstrap_fork_open)
{
nano::test::system system;
nano::node_config node_config (system.get_available_port (), system.logging);
nano::node_config node_config (system.get_available_port ());
auto node0 = system.add_node (node_config);
node_config.peering_port = system.get_available_port ();
auto node1 = system.add_node (node_config);
@ -1688,7 +1684,7 @@ TEST (node, rep_weight)
{
nano::test::system system;
auto add_node = [&system] {
auto node = std::make_shared<nano::node> (system.io_ctx, system.get_available_port (), nano::unique_path (), system.logging, system.work);
auto node = std::make_shared<nano::node> (system.io_ctx, system.get_available_port (), nano::unique_path (), system.work);
node->start ();
system.nodes.push_back (node);
return node;
@ -1858,7 +1854,7 @@ TEST (node, rep_remove)
ASSERT_TIMELY_EQ (5s, searching_node.rep_crawler.representative_count (), 0);
// Add working node for genesis representative
auto node_genesis_rep = system.add_node (nano::node_config (system.get_available_port (), system.logging));
auto node_genesis_rep = system.add_node (nano::node_config (system.get_available_port ()));
system.wallet (1)->insert_adhoc (nano::dev::genesis_key.prv);
auto channel_genesis_rep (searching_node.network.find_node_id (node_genesis_rep->get_node_id ()));
ASSERT_NE (nullptr, channel_genesis_rep);
@ -1869,7 +1865,7 @@ TEST (node, rep_remove)
ASSERT_TIMELY_EQ (10s, searching_node.rep_crawler.representative_count (), 1);
// Start a node for Rep2 and wait until it is connected
auto node_rep2 (std::make_shared<nano::node> (system.io_ctx, nano::unique_path (), nano::node_config (system.get_available_port (), system.logging), system.work));
auto node_rep2 (std::make_shared<nano::node> (system.io_ctx, nano::unique_path (), nano::node_config (system.get_available_port ()), system.work));
node_rep2->start ();
searching_node.network.tcp_channels.start_tcp (node_rep2->network.endpoint ());
std::shared_ptr<nano::transport::channel> channel_rep2;
@ -1910,7 +1906,7 @@ TEST (node, no_voting)
{
nano::test::system system (1);
auto & node0 (*system.nodes[0]);
nano::node_config node_config (system.get_available_port (), system.logging);
nano::node_config node_config (system.get_available_port ());
node_config.enable_voting = false;
system.add_node (node_config);
@ -2234,7 +2230,7 @@ TEST (node, confirm_quorum)
TEST (node, local_votes_cache)
{
nano::test::system system;
nano::node_config node_config (system.get_available_port (), system.logging);
nano::node_config node_config (system.get_available_port ());
node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled;
node_config.receive_minimum = nano::dev::constants.genesis_amount;
auto & node (*system.add_node (node_config));
@ -2322,7 +2318,7 @@ TEST (node, local_votes_cache)
TEST (node, DISABLED_local_votes_cache_batch)
{
nano::test::system system;
nano::node_config node_config (system.get_available_port (), system.logging);
nano::node_config node_config (system.get_available_port ());
node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled;
auto & node (*system.add_node (node_config));
ASSERT_GE (node.network_params.voting.max_cache, 2);
@ -2395,7 +2391,7 @@ TEST (node, DISABLED_local_votes_cache_batch)
TEST (node, local_votes_cache_generate_new_vote)
{
nano::test::system system;
nano::node_config node_config (system.get_available_port (), system.logging);
nano::node_config node_config (system.get_available_port ());
node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled;
auto & node (*system.add_node (node_config));
system.wallet (0)->insert_adhoc (nano::dev::genesis_key.prv);
@ -2448,7 +2444,7 @@ TEST (node, local_votes_cache_fork)
node_flags.disable_lazy_bootstrap = true;
node_flags.disable_legacy_bootstrap = true;
node_flags.disable_wallet_bootstrap = true;
nano::node_config node_config (system.get_available_port (), system.logging);
nano::node_config node_config (system.get_available_port ());
node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled;
auto & node1 (*system.add_node (node_config, node_flags));
system.wallet (0)->insert_adhoc (nano::dev::genesis_key.prv);
@ -2699,7 +2695,7 @@ TEST (node, DISABLED_vote_by_hash_epoch_block_republish)
TEST (node, epoch_conflict_confirm)
{
nano::test::system system;
nano::node_config node_config (system.get_available_port (), system.logging);
nano::node_config node_config (system.get_available_port ());
node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled;
auto & node0 = *system.add_node (node_config);
node_config.peering_port = system.get_available_port ();
@ -3030,7 +3026,7 @@ TEST (node, block_processor_full)
nano::node_flags node_flags;
node_flags.force_use_write_database_queue = true;
node_flags.block_processor_full_size = 3;
auto & node = *system.add_node (nano::node_config (system.get_available_port (), system.logging), node_flags);
auto & node = *system.add_node (nano::node_config (system.get_available_port ()), node_flags);
nano::state_block_builder builder;
auto send1 = builder.make_block ()
.account (nano::dev::genesis_key.pub)
@ -3075,7 +3071,7 @@ TEST (node, block_processor_half_full)
nano::node_flags node_flags;
node_flags.block_processor_full_size = 6;
node_flags.force_use_write_database_queue = true;
auto & node = *system.add_node (nano::node_config (system.get_available_port (), system.logging), node_flags);
auto & node = *system.add_node (nano::node_config (system.get_available_port ()), node_flags);
nano::state_block_builder builder;
auto send1 = builder.make_block ()
.account (nano::dev::genesis_key.pub)
@ -3167,7 +3163,7 @@ TEST (node, peers)
auto node1 (system.nodes[0]);
ASSERT_TRUE (node1->network.empty ());
auto node2 (std::make_shared<nano::node> (system.io_ctx, system.get_available_port (), nano::unique_path (), system.logging, system.work));
auto node2 (std::make_shared<nano::node> (system.io_ctx, system.get_available_port (), nano::unique_path (), system.work));
system.nodes.push_back (node2);
auto endpoint = node1->network.endpoint ();
@ -3217,7 +3213,7 @@ TEST (node, peer_cache_restart)
nano::endpoint_key endpoint_key{ endpoint.address ().to_v6 ().to_bytes (), endpoint.port () };
auto path (nano::unique_path ());
{
auto node2 (std::make_shared<nano::node> (system.io_ctx, system.get_available_port (), path, system.logging, system.work));
auto node2 (std::make_shared<nano::node> (system.io_ctx, system.get_available_port (), path, system.work));
system.nodes.push_back (node2);
auto & store = node2->store;
{
@ -3237,7 +3233,7 @@ TEST (node, peer_cache_restart)
{
nano::node_flags node_flags;
node_flags.read_only = true;
auto node3 (std::make_shared<nano::node> (system.io_ctx, system.get_available_port (), path, system.logging, system.work, node_flags));
auto node3 (std::make_shared<nano::node> (system.io_ctx, system.get_available_port (), path, system.work, node_flags));
system.nodes.push_back (node3);
// Check cached peers after restart
node3->network.start ();
@ -3305,7 +3301,7 @@ TEST (node, dont_write_lock_node)
std::promise<void> write_lock_held_promise;
std::promise<void> finished_promise;
std::thread ([&path, &write_lock_held_promise, &finished_promise] () {
nano::logger_mt logger;
nano::logger logger;
auto store = nano::make_store (logger, path, nano::dev::constants, false, true);
{
nano::ledger_cache ledger_cache;
@ -3342,7 +3338,7 @@ TEST (node, bidirectional_tcp)
node_flags.disable_legacy_bootstrap = true;
node_flags.disable_lazy_bootstrap = true;
node_flags.disable_wallet_bootstrap = true;
nano::node_config node_config (system.get_available_port (), system.logging);
nano::node_config node_config (system.get_available_port ());
node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled;
auto node1 = system.add_node (node_config, node_flags);
node_config.peering_port = system.get_available_port ();
@ -3540,7 +3536,7 @@ TEST (node, rollback_vote_self)
TEST (node, rollback_gap_source)
{
nano::test::system system;
nano::node_config node_config (system.get_available_port (), system.logging);
nano::node_config node_config (system.get_available_port ());
node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled;
auto & node = *system.add_node (node_config);
nano::state_block_builder builder;
@ -3608,7 +3604,7 @@ TEST (node, rollback_gap_source)
TEST (node, dependency_graph)
{
nano::test::system system;
nano::node_config config (system.get_available_port (), system.logging);
nano::node_config config (system.get_available_port ());
config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled;
auto & node = *system.add_node (config);
@ -3806,7 +3802,7 @@ TEST (node, dependency_graph)
TEST (node, dependency_graph_frontier)
{
nano::test::system system;
nano::node_config config (system.get_available_port (), system.logging);
nano::node_config config (system.get_available_port ());
config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled;
auto & node1 = *system.add_node (config);
config.peering_port = system.get_available_port ();
@ -3973,9 +3969,9 @@ namespace nano
TEST (node, deferred_dependent_elections)
{
nano::test::system system;
nano::node_config node_config_1{ system.get_available_port (), system.logging };
nano::node_config node_config_1{ system.get_available_port () };
node_config_1.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled;
nano::node_config node_config_2{ system.get_available_port (), system.logging };
nano::node_config node_config_2{ system.get_available_port () };
node_config_2.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled;
nano::node_flags flags;
flags.disable_request_loop = true;
@ -4138,7 +4134,7 @@ TEST (node, pruning_automatic)
{
nano::test::system system{};
nano::node_config node_config{ system.get_available_port (), system.logging };
nano::node_config node_config{ system.get_available_port () };
// TODO: remove after allowing pruned voting
node_config.enable_voting = false;
node_config.max_pruning_age = std::chrono::seconds (1);
@ -4193,7 +4189,7 @@ TEST (node, pruning_age)
{
nano::test::system system{};
nano::node_config node_config{ system.get_available_port (), system.logging };
nano::node_config node_config{ system.get_available_port () };
// TODO: remove after allowing pruned voting
node_config.enable_voting = false;
@ -4235,13 +4231,13 @@ TEST (node, pruning_age)
ASSERT_EQ (3, node1.ledger.cache.block_count);
// Pruning with default age 1 day
node1.ledger_pruning (1, true, false);
node1.ledger_pruning (1, true);
ASSERT_EQ (0, node1.ledger.cache.pruned_count);
ASSERT_EQ (3, node1.ledger.cache.block_count);
// Pruning with max age 0
node1.config.max_pruning_age = std::chrono::seconds{ 0 };
node1.ledger_pruning (1, true, false);
node1.ledger_pruning (1, true);
ASSERT_EQ (1, node1.ledger.cache.pruned_count);
ASSERT_EQ (3, node1.ledger.cache.block_count);
@ -4256,7 +4252,7 @@ TEST (node, pruning_depth)
{
nano::test::system system{};
nano::node_config node_config{ system.get_available_port (), system.logging };
nano::node_config node_config{ system.get_available_port () };
// TODO: remove after allowing pruned voting
node_config.enable_voting = false;
@ -4298,13 +4294,13 @@ TEST (node, pruning_depth)
ASSERT_EQ (3, node1.ledger.cache.block_count);
// Pruning with default depth (unlimited)
node1.ledger_pruning (1, true, false);
node1.ledger_pruning (1, true);
ASSERT_EQ (0, node1.ledger.cache.pruned_count);
ASSERT_EQ (3, node1.ledger.cache.block_count);
// Pruning with max depth 1
node1.config.max_pruning_depth = 1;
node1.ledger_pruning (1, true, false);
node1.ledger_pruning (1, true);
ASSERT_EQ (1, node1.ledger.cache.pruned_count);
ASSERT_EQ (3, node1.ledger.cache.block_count);
@ -4315,27 +4311,27 @@ TEST (node, pruning_depth)
TEST (node_config, node_id_private_key_persistence)
{
nano::logger_mt logger;
nano::test::system system;
// create the directory and the file
auto path = nano::unique_path ();
ASSERT_TRUE (std::filesystem::create_directories (path));
ASSERT_TRUE (std::filesystem::exists (path));
auto priv_key_filename = path / "node_id_private.key";
// check that the key generated is random when the key does not exist
nano::keypair kp1 = nano::load_or_create_node_id (path, logger);
nano::keypair kp1 = nano::load_or_create_node_id (path);
std::filesystem::remove (priv_key_filename);
nano::keypair kp2 = nano::load_or_create_node_id (path, logger);
nano::keypair kp2 = nano::load_or_create_node_id (path);
ASSERT_NE (kp1.prv, kp2.prv);
// check that the key persists
nano::keypair kp3 = nano::load_or_create_node_id (path, logger);
nano::keypair kp3 = nano::load_or_create_node_id (path);
ASSERT_EQ (kp2.prv, kp3.prv);
// write the key file manually and check that right key is loaded
std::ofstream ofs (priv_key_filename.string (), std::ofstream::out | std::ofstream::trunc);
ofs << "3F28D035B8AA75EA53DF753BFD065CF6138E742971B2C99B84FD8FE328FED2D9" << std::flush;
ofs.close ();
nano::keypair kp4 = nano::load_or_create_node_id (path, logger);
nano::keypair kp4 = nano::load_or_create_node_id (path);
ASSERT_EQ (kp4.prv, nano::keypair ("3F28D035B8AA75EA53DF753BFD065CF6138E742971B2C99B84FD8FE328FED2D9").prv);
}

View file

@ -1,3 +1,4 @@
#include <nano/lib/logging.hpp>
#include <nano/lib/stats.hpp>
#include <nano/lib/work.hpp>
#include <nano/node/make_store.hpp>
@ -10,7 +11,7 @@
TEST (processor_service, bad_send_signature)
{
nano::logger_mt logger;
nano::logger logger;
auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants);
ASSERT_FALSE (store->init_error ());
nano::stats stats;
@ -36,7 +37,7 @@ TEST (processor_service, bad_send_signature)
TEST (processor_service, bad_receive_signature)
{
nano::logger_mt logger;
nano::logger logger;
auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants);
ASSERT_FALSE (store->init_error ());
nano::stats stats;

View file

@ -196,35 +196,6 @@ TEST (toml, daemon_config_deserialize_defaults)
ASSERT_EQ (conf.node.backlog_scan_batch_size, defaults.node.backlog_scan_batch_size);
ASSERT_EQ (conf.node.backlog_scan_frequency, defaults.node.backlog_scan_frequency);
ASSERT_EQ (conf.node.logging.bulk_pull_logging_value, defaults.node.logging.bulk_pull_logging_value);
ASSERT_EQ (conf.node.logging.flush, defaults.node.logging.flush);
ASSERT_EQ (conf.node.logging.insufficient_work_logging_value, defaults.node.logging.insufficient_work_logging_value);
ASSERT_EQ (conf.node.logging.ledger_logging_value, defaults.node.logging.ledger_logging_value);
ASSERT_EQ (conf.node.logging.ledger_duplicate_logging_value, defaults.node.logging.ledger_duplicate_logging_value);
ASSERT_EQ (conf.node.logging.log_ipc_value, defaults.node.logging.log_ipc_value);
ASSERT_EQ (conf.node.logging.log_to_cerr_value, defaults.node.logging.log_to_cerr_value);
ASSERT_EQ (conf.node.logging.max_size, defaults.node.logging.max_size);
ASSERT_EQ (conf.node.logging.min_time_between_log_output.count (), defaults.node.logging.min_time_between_log_output.count ());
ASSERT_EQ (conf.node.logging.network_logging_value, defaults.node.logging.network_logging_value);
ASSERT_EQ (conf.node.logging.network_keepalive_logging_value, defaults.node.logging.network_keepalive_logging_value);
ASSERT_EQ (conf.node.logging.network_message_logging_value, defaults.node.logging.network_message_logging_value);
ASSERT_EQ (conf.node.logging.network_node_id_handshake_logging_value, defaults.node.logging.network_node_id_handshake_logging_value);
ASSERT_EQ (conf.node.logging.network_packet_logging_value, defaults.node.logging.network_packet_logging_value);
ASSERT_EQ (conf.node.logging.network_publish_logging_value, defaults.node.logging.network_publish_logging_value);
ASSERT_EQ (conf.node.logging.network_timeout_logging_value, defaults.node.logging.network_timeout_logging_value);
ASSERT_EQ (conf.node.logging.node_lifetime_tracing_value, defaults.node.logging.node_lifetime_tracing_value);
ASSERT_EQ (conf.node.logging.network_telemetry_logging_value, defaults.node.logging.network_telemetry_logging_value);
ASSERT_EQ (conf.node.logging.network_rejected_logging_value, defaults.node.logging.network_rejected_logging_value);
ASSERT_EQ (conf.node.logging.rotation_size, defaults.node.logging.rotation_size);
ASSERT_EQ (conf.node.logging.single_line_record_value, defaults.node.logging.single_line_record_value);
ASSERT_EQ (conf.node.logging.stable_log_filename, defaults.node.logging.stable_log_filename);
ASSERT_EQ (conf.node.logging.timing_logging_value, defaults.node.logging.timing_logging_value);
ASSERT_EQ (conf.node.logging.active_update_value, defaults.node.logging.active_update_value);
ASSERT_EQ (conf.node.logging.upnp_details_logging_value, defaults.node.logging.upnp_details_logging_value);
ASSERT_EQ (conf.node.logging.vote_logging_value, defaults.node.logging.vote_logging_value);
ASSERT_EQ (conf.node.logging.rep_crawler_logging_value, defaults.node.logging.rep_crawler_logging_value);
ASSERT_EQ (conf.node.logging.work_generation_time_value, defaults.node.logging.work_generation_time_value);
ASSERT_EQ (conf.node.websocket_config.enabled, defaults.node.websocket_config.enabled);
ASSERT_EQ (conf.node.websocket_config.address, defaults.node.websocket_config.address);
ASSERT_EQ (conf.node.websocket_config.port, defaults.node.websocket_config.port);
@ -642,35 +613,6 @@ TEST (toml, daemon_config_deserialize_no_defaults)
ASSERT_NE (conf.node.backlog_scan_batch_size, defaults.node.backlog_scan_batch_size);
ASSERT_NE (conf.node.backlog_scan_frequency, defaults.node.backlog_scan_frequency);
ASSERT_NE (conf.node.logging.bulk_pull_logging_value, defaults.node.logging.bulk_pull_logging_value);
ASSERT_NE (conf.node.logging.flush, defaults.node.logging.flush);
ASSERT_NE (conf.node.logging.insufficient_work_logging_value, defaults.node.logging.insufficient_work_logging_value);
ASSERT_NE (conf.node.logging.ledger_logging_value, defaults.node.logging.ledger_logging_value);
ASSERT_NE (conf.node.logging.ledger_duplicate_logging_value, defaults.node.logging.ledger_duplicate_logging_value);
ASSERT_NE (conf.node.logging.log_ipc_value, defaults.node.logging.log_ipc_value);
ASSERT_NE (conf.node.logging.log_to_cerr_value, defaults.node.logging.log_to_cerr_value);
ASSERT_NE (conf.node.logging.max_size, defaults.node.logging.max_size);
ASSERT_NE (conf.node.logging.min_time_between_log_output.count (), defaults.node.logging.min_time_between_log_output.count ());
ASSERT_NE (conf.node.logging.network_logging_value, defaults.node.logging.network_logging_value);
ASSERT_NE (conf.node.logging.network_keepalive_logging_value, defaults.node.logging.network_keepalive_logging_value);
ASSERT_NE (conf.node.logging.network_message_logging_value, defaults.node.logging.network_message_logging_value);
ASSERT_NE (conf.node.logging.network_node_id_handshake_logging_value, defaults.node.logging.network_node_id_handshake_logging_value);
ASSERT_NE (conf.node.logging.network_telemetry_logging_value, defaults.node.logging.network_telemetry_logging_value);
ASSERT_NE (conf.node.logging.network_rejected_logging_value, defaults.node.logging.network_rejected_logging_value);
ASSERT_NE (conf.node.logging.network_packet_logging_value, defaults.node.logging.network_packet_logging_value);
ASSERT_NE (conf.node.logging.network_publish_logging_value, defaults.node.logging.network_publish_logging_value);
ASSERT_NE (conf.node.logging.network_timeout_logging_value, defaults.node.logging.network_timeout_logging_value);
ASSERT_NE (conf.node.logging.node_lifetime_tracing_value, defaults.node.logging.node_lifetime_tracing_value);
ASSERT_NE (conf.node.logging.rotation_size, defaults.node.logging.rotation_size);
ASSERT_NE (conf.node.logging.single_line_record_value, defaults.node.logging.single_line_record_value);
ASSERT_NE (conf.node.logging.stable_log_filename, defaults.node.logging.stable_log_filename);
ASSERT_NE (conf.node.logging.timing_logging_value, defaults.node.logging.timing_logging_value);
ASSERT_NE (conf.node.logging.active_update_value, defaults.node.logging.active_update_value);
ASSERT_NE (conf.node.logging.upnp_details_logging_value, defaults.node.logging.upnp_details_logging_value);
ASSERT_NE (conf.node.logging.vote_logging_value, defaults.node.logging.vote_logging_value);
ASSERT_NE (conf.node.logging.rep_crawler_logging_value, defaults.node.logging.rep_crawler_logging_value);
ASSERT_NE (conf.node.logging.work_generation_time_value, defaults.node.logging.work_generation_time_value);
ASSERT_NE (conf.node.websocket_config.enabled, defaults.node.websocket_config.enabled);
ASSERT_NE (conf.node.websocket_config.address, defaults.node.websocket_config.address);
ASSERT_NE (conf.node.websocket_config.port, defaults.node.websocket_config.port);
@ -975,3 +917,92 @@ TEST (toml, tls_config_defaults)
ASSERT_EQ (conf.server_key_passphrase, defaults.server_key_passphrase);
ASSERT_EQ (conf.server_dh_path, defaults.server_dh_path);
}
TEST (toml, log_config_defaults)
{
std::stringstream ss;
// A config with no values
ss << R"toml()toml";
nano::tomlconfig toml;
toml.read (ss);
nano::log_config confg{};
nano::log_config defaults{};
confg.deserialize_toml (toml);
ASSERT_FALSE (toml.get_error ()) << toml.get_error ().get_message ();
ASSERT_EQ (confg.default_level, defaults.default_level);
ASSERT_EQ (confg.flush_level, defaults.flush_level);
ASSERT_EQ (confg.levels, defaults.levels);
ASSERT_EQ (confg.console.enable, defaults.console.enable);
ASSERT_EQ (confg.console.colors, defaults.console.colors);
ASSERT_EQ (confg.console.to_cerr, defaults.console.to_cerr);
ASSERT_EQ (confg.file.enable, defaults.file.enable);
ASSERT_EQ (confg.file.max_size, defaults.file.max_size);
ASSERT_EQ (confg.file.rotation_count, defaults.file.rotation_count);
}
TEST (toml, log_config_no_defaults)
{
std::stringstream ss;
// A config file with values that differs from defaults
ss << R"toml(
[log]
default_level = "trace"
[log.console]
colors = false
enable = false
to_cerr = true
[log.file]
enable = false
max_size = 999
rotation_count = 999
[log.levels]
active_transactions = "trace"
blockprocessor = "trace"
)toml";
nano::tomlconfig toml;
toml.read (ss);
nano::log_config confg{};
nano::log_config defaults{};
confg.deserialize_toml (toml);
ASSERT_FALSE (toml.get_error ()) << toml.get_error ().get_message ();
ASSERT_NE (confg.default_level, defaults.default_level);
ASSERT_NE (confg.levels, defaults.levels);
ASSERT_NE (confg.console.enable, defaults.console.enable);
ASSERT_NE (confg.console.colors, defaults.console.colors);
ASSERT_NE (confg.console.to_cerr, defaults.console.to_cerr);
ASSERT_NE (confg.file.enable, defaults.file.enable);
ASSERT_NE (confg.file.max_size, defaults.file.max_size);
ASSERT_NE (confg.file.rotation_count, defaults.file.rotation_count);
}
TEST (toml, log_config_no_required)
{
std::stringstream ss;
// A config with no values, only categories
ss << R"toml(
[log]
[log.console]
[log.file]
[log.levels]
)toml";
nano::tomlconfig toml;
toml.read (ss);
nano::log_config confg{};
nano::log_config defaults{};
confg.deserialize_toml (toml);
ASSERT_FALSE (toml.get_error ()) << toml.get_error ().get_message ();
}

View file

@ -1,5 +1,4 @@
#include <nano/lib/blockbuilders.hpp>
#include <nano/lib/logger_mt.hpp>
#include <nano/lib/stats.hpp>
#include <nano/node/unchecked_map.hpp>
#include <nano/secure/common.hpp>

View file

@ -12,7 +12,7 @@ unsigned constexpr nano::wallet_store::version_current;
TEST (wallet, no_special_keys_accounts)
{
bool init;
nano::store::lmdb::env env (init, nano::unique_path ());
nano::store::lmdb::env env (init, nano::unique_path () / "wallet.ldb");
ASSERT_FALSE (init);
auto transaction (env.tx_begin_write ());
nano::kdf kdf{ nano::dev::network_params.kdf_work };
@ -33,7 +33,7 @@ TEST (wallet, no_special_keys_accounts)
TEST (wallet, no_key)
{
bool init;
nano::store::lmdb::env env (init, nano::unique_path ());
nano::store::lmdb::env env (init, nano::unique_path () / "wallet.ldb");
ASSERT_FALSE (init);
auto transaction (env.tx_begin_write ());
nano::kdf kdf{ nano::dev::network_params.kdf_work };
@ -48,7 +48,7 @@ TEST (wallet, no_key)
TEST (wallet, fetch_locked)
{
bool init;
nano::store::lmdb::env env (init, nano::unique_path ());
nano::store::lmdb::env env (init, nano::unique_path () / "wallet.ldb");
ASSERT_FALSE (init);
auto transaction (env.tx_begin_write ());
nano::kdf kdf{ nano::dev::network_params.kdf_work };
@ -70,7 +70,7 @@ TEST (wallet, fetch_locked)
TEST (wallet, retrieval)
{
bool init;
nano::store::lmdb::env env (init, nano::unique_path ());
nano::store::lmdb::env env (init, nano::unique_path () / "wallet.ldb");
ASSERT_FALSE (init);
auto transaction (env.tx_begin_write ());
nano::kdf kdf{ nano::dev::network_params.kdf_work };
@ -92,7 +92,7 @@ TEST (wallet, retrieval)
TEST (wallet, empty_iteration)
{
bool init;
nano::store::lmdb::env env (init, nano::unique_path ());
nano::store::lmdb::env env (init, nano::unique_path () / "wallet.ldb");
ASSERT_FALSE (init);
auto transaction (env.tx_begin_write ());
nano::kdf kdf{ nano::dev::network_params.kdf_work };
@ -106,7 +106,7 @@ TEST (wallet, empty_iteration)
TEST (wallet, one_item_iteration)
{
bool init;
nano::store::lmdb::env env (init, nano::unique_path ());
nano::store::lmdb::env env (init, nano::unique_path () / "wallet.ldb");
ASSERT_FALSE (init);
auto transaction (env.tx_begin_write ());
nano::kdf kdf{ nano::dev::network_params.kdf_work };
@ -128,7 +128,7 @@ TEST (wallet, one_item_iteration)
TEST (wallet, two_item_iteration)
{
bool init;
nano::store::lmdb::env env (init, nano::unique_path ());
nano::store::lmdb::env env (init, nano::unique_path () / "wallet.ldb");
ASSERT_FALSE (init);
nano::keypair key1;
nano::keypair key2;
@ -267,7 +267,7 @@ TEST (wallet, spend_no_previous)
TEST (wallet, find_none)
{
bool init;
nano::store::lmdb::env env (init, nano::unique_path ());
nano::store::lmdb::env env (init, nano::unique_path () / "wallet.ldb");
ASSERT_FALSE (init);
auto transaction (env.tx_begin_write ());
nano::kdf kdf{ nano::dev::network_params.kdf_work };
@ -280,7 +280,7 @@ TEST (wallet, find_none)
TEST (wallet, find_existing)
{
bool init;
nano::store::lmdb::env env (init, nano::unique_path ());
nano::store::lmdb::env env (init, nano::unique_path () / "wallet.ldb");
ASSERT_FALSE (init);
auto transaction (env.tx_begin_write ());
nano::kdf kdf{ nano::dev::network_params.kdf_work };
@ -299,7 +299,7 @@ TEST (wallet, find_existing)
TEST (wallet, rekey)
{
bool init;
nano::store::lmdb::env env (init, nano::unique_path ());
nano::store::lmdb::env env (init, nano::unique_path () / "wallet.ldb");
ASSERT_FALSE (init);
auto transaction (env.tx_begin_write ());
nano::kdf kdf{ nano::dev::network_params.kdf_work };
@ -371,7 +371,7 @@ TEST (account, encode_fail)
TEST (wallet, hash_password)
{
bool init;
nano::store::lmdb::env env (init, nano::unique_path ());
nano::store::lmdb::env env (init, nano::unique_path () / "wallet.ldb");
ASSERT_FALSE (init);
auto transaction (env.tx_begin_write ());
nano::kdf kdf{ nano::dev::network_params.kdf_work };
@ -420,7 +420,7 @@ TEST (fan, change)
TEST (wallet, reopen_default_password)
{
bool init;
nano::store::lmdb::env env (init, nano::unique_path ());
nano::store::lmdb::env env (init, nano::unique_path () / "wallet.ldb");
auto transaction (env.tx_begin_write ());
ASSERT_FALSE (init);
nano::kdf kdf{ nano::dev::network_params.kdf_work };
@ -456,7 +456,7 @@ TEST (wallet, reopen_default_password)
TEST (wallet, representative)
{
auto error (false);
nano::store::lmdb::env env (error, nano::unique_path ());
nano::store::lmdb::env env (error, nano::unique_path () / "wallet.ldb");
ASSERT_FALSE (error);
auto transaction (env.tx_begin_write ());
nano::kdf kdf{ nano::dev::network_params.kdf_work };
@ -477,7 +477,7 @@ TEST (wallet, representative)
TEST (wallet, serialize_json_empty)
{
auto error (false);
nano::store::lmdb::env env (error, nano::unique_path ());
nano::store::lmdb::env env (error, nano::unique_path () / "wallet.ldb");
ASSERT_FALSE (error);
auto transaction (env.tx_begin_write ());
nano::kdf kdf{ nano::dev::network_params.kdf_work };
@ -502,7 +502,7 @@ TEST (wallet, serialize_json_empty)
TEST (wallet, serialize_json_one)
{
auto error (false);
nano::store::lmdb::env env (error, nano::unique_path ());
nano::store::lmdb::env env (error, nano::unique_path () / "wallet.ldb");
ASSERT_FALSE (error);
auto transaction (env.tx_begin_write ());
nano::kdf kdf{ nano::dev::network_params.kdf_work };
@ -531,7 +531,7 @@ TEST (wallet, serialize_json_one)
TEST (wallet, serialize_json_password)
{
auto error (false);
nano::store::lmdb::env env (error, nano::unique_path ());
nano::store::lmdb::env env (error, nano::unique_path () / "wallet.ldb");
ASSERT_FALSE (error);
auto transaction (env.tx_begin_write ());
nano::kdf kdf{ nano::dev::network_params.kdf_work };
@ -564,7 +564,7 @@ TEST (wallet, serialize_json_password)
TEST (wallet_store, move)
{
auto error (false);
nano::store::lmdb::env env (error, nano::unique_path ());
nano::store::lmdb::env env (error, nano::unique_path () / "wallet.ldb");
ASSERT_FALSE (error);
auto transaction (env.tx_begin_write ());
nano::kdf kdf{ nano::dev::network_params.kdf_work };
@ -722,7 +722,7 @@ TEST (wallet, insert_locked)
TEST (wallet, deterministic_keys)
{
bool init;
nano::store::lmdb::env env (init, nano::unique_path ());
nano::store::lmdb::env env (init, nano::unique_path () / "wallet.ldb");
ASSERT_FALSE (init);
auto transaction (env.tx_begin_write ());
nano::kdf kdf{ nano::dev::network_params.kdf_work };
@ -765,7 +765,7 @@ TEST (wallet, deterministic_keys)
TEST (wallet, reseed)
{
bool init;
nano::store::lmdb::env env (init, nano::unique_path ());
nano::store::lmdb::env env (init, nano::unique_path () / "wallet.ldb");
ASSERT_FALSE (init);
auto transaction (env.tx_begin_write ());
nano::kdf kdf{ nano::dev::network_params.kdf_work };

View file

@ -1,9 +1,8 @@
#include <nano/crypto_lib/random_pool.hpp>
#include <nano/lib/blocks.hpp>
#include <nano/lib/logger_mt.hpp>
#include <nano/lib/logging.hpp>
#include <nano/lib/timer.hpp>
#include <nano/lib/work.hpp>
#include <nano/node/logging.hpp>
#include <nano/node/openclconfig.hpp>
#include <nano/node/openclwork.hpp>
#include <nano/secure/common.hpp>
@ -90,9 +89,7 @@ TEST (work, cancel_many)
TEST (work, opencl)
{
nano::logging logging;
logging.init (nano::unique_path ());
nano::logger_mt logger;
nano::logger logger;
bool error (false);
nano::opencl_environment environment (error);
ASSERT_TRUE (!error || !nano::opencl_loaded);

View file

@ -50,7 +50,10 @@ add_library(
lmdbconfig.cpp
locks.hpp
locks.cpp
logger_mt.hpp
logging.hpp
logging.cpp
logging_enums.hpp
logging_enums.cpp
memory.hpp
memory.cpp
numbers.hpp
@ -100,7 +103,6 @@ add_library(
work.cpp)
include_directories(${CMAKE_SOURCE_DIR}/submodules)
include_directories(${CMAKE_SOURCE_DIR}/submodules/cpptoml/include)
include_directories(
${CMAKE_SOURCE_DIR}/submodules/nano-pow-server/deps/cpptoml/include)
@ -111,12 +113,12 @@ target_link_libraries(
blake2
${CRYPTOPP_LIBRARY}
${CMAKE_DL_LIBS}
fmt::fmt
spdlog::spdlog
Boost::iostreams
Boost::asio
Boost::circular_buffer
Boost::dll
Boost::log_setup
Boost::log
Boost::multiprecision
Boost::program_options
Boost::stacktrace)

View file

@ -11,6 +11,7 @@
#include <bitset>
#include <cryptopp/words.h>
#include <magic_enum.hpp>
/** Compare blocks, first by type, then content. This is an optimization over dynamic_cast, which is very slow on some platforms. */
namespace
@ -1864,3 +1865,8 @@ bool nano::block_sideband::deserialize (nano::stream & stream_a, nano::block_typ
return result;
}
std::string_view nano::to_string (nano::block_type type)
{
return magic_enum::enum_name (type);
}

View file

@ -29,6 +29,9 @@ enum class block_type : uint8_t
change = 5,
state = 6
};
std::string_view to_string (block_type);
class block_details
{
static_assert (std::is_same<std::underlying_type<nano::epoch>::type, uint8_t> (), "Epoch enum is not the proper type");

View file

@ -1,5 +1,6 @@
#include <nano/lib/blocks.hpp>
#include <nano/lib/config.hpp>
#include <nano/lib/logging.hpp>
#include <boost/format.hpp>
#include <boost/lexical_cast.hpp>
@ -355,3 +356,60 @@ uint32_t nano::test_scan_wallet_reps_delay ()
auto test_env = nano::get_env_or_default ("NANO_TEST_WALLET_SCAN_REPS_DELAY", "900000"); // 15 minutes by default
return boost::lexical_cast<uint32_t> (test_env);
}
std::string_view nano::to_string (nano::networks network)
{
switch (network)
{
case nano::networks::invalid:
return "invalid";
case nano::networks::nano_beta_network:
return "beta";
case nano::networks::nano_dev_network:
return "dev";
case nano::networks::nano_live_network:
return "live";
case nano::networks::nano_test_network:
return "test";
// default case intentionally omitted to cause warnings for unhandled enums
}
return "n/a";
}
// Using std::cerr here, since logging may not be initialized yet
nano::tomlconfig nano::load_toml_file (const std::filesystem::path & config_filename, const std::filesystem::path & data_path, const std::vector<std::string> & config_overrides)
{
std::stringstream config_overrides_stream;
for (auto const & entry : config_overrides)
{
config_overrides_stream << entry << std::endl;
}
config_overrides_stream << std::endl;
// Make sure we don't create an empty toml file if it doesn't exist. Running without a toml file is the default.
auto toml_config_path = data_path / config_filename;
if (std::filesystem::exists (toml_config_path))
{
nano::tomlconfig toml;
auto error = toml.read (config_overrides_stream, toml_config_path);
if (error)
{
throw std::runtime_error (error.get_message ());
}
std::cerr << "Config file `" << config_filename.string () << "` loaded from node data directory: " << toml_config_path.string () << std::endl;
return toml;
}
else
{
// If no config was found, return an empty config with overrides applied
nano::tomlconfig toml;
auto error = toml.read (config_overrides_stream);
if (error)
{
throw std::runtime_error (error.get_message ());
}
std::cerr << "Config file `" << config_filename.string () << "` not found, using default configuration" << std::endl;
return toml;
}
}

View file

@ -1,5 +1,7 @@
#pragma once
#include <nano/lib/tomlconfig.hpp>
#include <boost/config.hpp>
#include <boost/version.hpp>
@ -127,6 +129,8 @@ enum class networks : uint16_t
nano_test_network = 0x5258, // 'R', 'X'
};
std::string_view to_string (nano::networks);
enum class work_version
{
unspecified,
@ -404,4 +408,28 @@ bool is_sanitizer_build ();
/** Set the active network to the dev network */
void force_nano_dev_network ();
/**
* Attempt to read a configuration file from specified directory. Returns empty tomlconfig if nothing is found.
* @throws std::runtime_error with error code if the file or overrides are not valid toml
*/
nano::tomlconfig load_toml_file (const std::filesystem::path & config_filename, const std::filesystem::path & data_path, const std::vector<std::string> & config_overrides);
/**
* Attempt to read a configuration file from specified directory. Returns fallback config if nothing is found.
* @throws std::runtime_error with error code if the file or overrides are not valid toml or deserialization fails
*/
template <typename T>
T load_config_file (T fallback, const std::filesystem::path & config_filename, const std::filesystem::path & data_path, const std::vector<std::string> & config_overrides)
{
auto toml = load_toml_file (config_filename, data_path, config_overrides);
T config = fallback;
auto error = config.deserialize_toml (toml);
if (error)
{
throw std::runtime_error (error.get_message ());
}
return config;
}
}

View file

@ -1,139 +0,0 @@
#pragma once
#include <nano/lib/locks.hpp>
#include <nano/lib/utility.hpp>
#include <boost/log/sources/severity_logger.hpp>
#include <boost/log/trivial.hpp>
#include <boost/log/utility/manipulators/to_log.hpp>
#include <array>
#include <chrono>
#include <mutex>
namespace nano
{
enum class severity_level
{
normal = 0,
error
};
}
// Attribute value tag type
struct severity_tag;
inline boost::log::formatting_ostream & operator<< (boost::log::formatting_ostream & strm, boost::log::to_log_manip<nano::severity_level, severity_tag> const & manip)
{
// Needs to match order in the severity_level enum
static std::array<char const *, 2> strings = {
"",
"Error: "
};
nano::severity_level level = manip.get ();
debug_assert (static_cast<int> (level) < strings.size ());
strm << strings[static_cast<int> (level)];
return strm;
}
namespace nano
{
// A wrapper around a boost logger object to allow minimum
// time spaced output to prevent logging happening too quickly.
class logger_mt
{
private:
void add_to_stream (boost::log::record_ostream & stream)
{
}
template <typename LogItem, typename... LogItems>
void add_to_stream (boost::log::record_ostream & stream, const LogItem & first_log_item, LogItems &&... remainder_log_items)
{
stream << first_log_item;
add_to_stream (stream, remainder_log_items...);
}
template <typename... LogItems>
void output (nano::severity_level severity_level, LogItems &&... log_items)
{
boost::log::record rec = boost_logger_mt.open_record (boost::log::keywords::severity = severity_level);
if (rec)
{
boost::log::record_ostream strm (rec);
add_to_stream (strm, std::forward<LogItems> (log_items)...);
strm.flush ();
boost_logger_mt.push_record (std::move (rec));
}
}
public:
logger_mt () = default;
/**
* @param min_log_delta_a The minimum time between successive output
*/
explicit logger_mt (std::chrono::milliseconds const & min_log_delta_a) :
min_log_delta (min_log_delta_a)
{
}
/*
* @param log_items A collection of objects with overloaded operator<< to be output to the log file
* @params severity_level The severity level that this log message should have.
*/
template <typename... LogItems>
void always_log (nano::severity_level severity_level, LogItems &&... log_items)
{
output (severity_level, std::forward<LogItems> (log_items)...);
}
/*
* @param log_items A collection of objects with overloaded operator<< to be output to the log file.
*/
template <typename... LogItems>
void always_log (LogItems &&... log_items)
{
always_log (nano::severity_level::normal, std::forward<LogItems> (log_items)...);
}
/*
* @param log_items Output to the log file if the last write was over min_log_delta time ago.
* @params severity_level The severity level that this log message should have.
* @return true if nothing was logged
*/
template <typename... LogItems>
bool try_log (nano::severity_level severity_level, LogItems &&... log_items)
{
auto error (true);
auto time_now = std::chrono::steady_clock::now ();
nano::unique_lock<nano::mutex> lk (last_log_time_mutex);
if (((time_now - last_log_time) > min_log_delta) || last_log_time == std::chrono::steady_clock::time_point{})
{
last_log_time = time_now;
lk.unlock ();
output (severity_level, std::forward<LogItems> (log_items)...);
error = false;
}
return error;
}
/*
* @param log_items Output to the log file if the last write was over min_log_delta time ago.
* @return true if nothing was logged
*/
template <typename... LogItems>
bool try_log (LogItems &&... log_items)
{
return try_log (nano::severity_level::normal, std::forward<LogItems> (log_items)...);
}
std::chrono::milliseconds min_log_delta{ 0 };
private:
nano::mutex last_log_time_mutex;
std::chrono::steady_clock::time_point last_log_time;
boost::log::sources::severity_logger_mt<severity_level> boost_logger_mt;
};
}

519
nano/lib/logging.cpp Normal file
View file

@ -0,0 +1,519 @@
#include <nano/lib/config.hpp>
#include <nano/lib/logging.hpp>
#include <nano/lib/utility.hpp>
#include <fmt/chrono.h>
#include <spdlog/pattern_formatter.h>
#include <spdlog/sinks/basic_file_sink.h>
#include <spdlog/sinks/rotating_file_sink.h>
#include <spdlog/sinks/stdout_color_sinks.h>
#include <spdlog/sinks/stdout_sinks.h>
nano::logger & nano::default_logger ()
{
static nano::logger logger{ "default" };
return logger;
}
/*
* logger
*/
bool nano::logger::global_initialized{ false };
nano::log_config nano::logger::global_config{};
std::vector<spdlog::sink_ptr> nano::logger::global_sinks{};
// By default, use only the tag as the logger name, since only one node is running in the process
std::function<std::string (nano::log::type tag, std::string identifier)> nano::logger::global_name_formatter{ [] (auto tag, auto identifier) {
return std::string{ to_string (tag) };
} };
void nano::logger::initialize (nano::log_config fallback, std::optional<std::filesystem::path> data_path, std::vector<std::string> const & config_overrides)
{
// Only load log config from file if data_path is available (i.e. not running in cli mode)
nano::log_config config = data_path ? nano::load_log_config (fallback, *data_path, config_overrides) : fallback;
initialize_common (config, data_path);
global_initialized = true;
}
// Custom log formatter flags
namespace
{
/// Takes a qualified identifier in the form `node_identifier::tag` and splits it into a pair of `identifier` and `tag`
/// It is a limitation of spldlog that we cannot attach additional data to the logger, so we have to encode the node identifier in the logger name
/// @returns <node identifier, tag>
std::pair<std::string_view, std::string_view> split_qualified_identifier (std::string_view qualified_identifier)
{
auto pos = qualified_identifier.find ("::");
debug_assert (pos != std::string_view::npos); // This should never happen, since the default logger name formatter always adds the tag
if (pos == std::string_view::npos)
{
return { std::string_view{}, qualified_identifier };
}
else
{
return { qualified_identifier.substr (0, pos), qualified_identifier.substr (pos + 2) };
}
}
class identifier_formatter_flag : public spdlog::custom_flag_formatter
{
public:
void format (const spdlog::details::log_msg & msg, const std::tm & tm, spdlog::memory_buf_t & dest) override
{
// Extract identifier and tag from logger name
auto [identifier, tag] = split_qualified_identifier (std::string_view (msg.logger_name.data (), msg.logger_name.size ()));
dest.append (identifier.data (), identifier.data () + identifier.size ());
}
std::unique_ptr<custom_flag_formatter> clone () const override
{
return spdlog::details::make_unique<identifier_formatter_flag> ();
}
};
class tag_formatter_flag : public spdlog::custom_flag_formatter
{
public:
void format (const spdlog::details::log_msg & msg, const std::tm & tm, spdlog::memory_buf_t & dest) override
{
// Extract identifier and tag from logger name
auto [identifier, tag] = split_qualified_identifier (std::string_view (msg.logger_name.data (), msg.logger_name.size ()));
dest.append (tag.data (), tag.data () + tag.size ());
}
std::unique_ptr<custom_flag_formatter> clone () const override
{
return spdlog::details::make_unique<tag_formatter_flag> ();
}
};
}
void nano::logger::initialize_for_tests (nano::log_config fallback)
{
auto config = nano::load_log_config (std::move (fallback), /* load log config from current workdir */ std::filesystem::current_path ());
initialize_common (config, /* store log file in current workdir */ std::filesystem::current_path ());
// Use tag and identifier as the logger name, since multiple nodes may be running in the same process
global_name_formatter = [] (nano::log::type tag, std::string identifier) {
return fmt::format ("{}::{}", identifier, to_string (tag));
};
// Setup formatter to include information about node identifier `[%i]` and tag `[%n]`
auto formatter = std::make_unique<spdlog::pattern_formatter> ();
formatter->add_flag<identifier_formatter_flag> ('i');
formatter->add_flag<tag_formatter_flag> ('n');
formatter->set_pattern ("[%Y-%m-%d %H:%M:%S.%e] [%i] [%n] [%l] %v");
for (auto & sink : global_sinks)
{
sink->set_formatter (formatter->clone ());
}
global_initialized = true;
}
// Using std::cerr here, since logging may not be initialized yet
void nano::logger::initialize_common (nano::log_config const & config, std::optional<std::filesystem::path> data_path)
{
global_config = config;
spdlog::set_automatic_registration (false);
spdlog::set_level (to_spdlog_level (config.default_level));
global_sinks.clear ();
// Console setup
if (config.console.enable)
{
if (!config.console.to_cerr)
{
// Only use colors if not writing to cerr
if (config.console.colors)
{
auto console_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt> ();
global_sinks.push_back (console_sink);
}
else
{
auto console_sink = std::make_shared<spdlog::sinks::stdout_sink_mt> ();
global_sinks.push_back (console_sink);
}
}
else
{
if (config.console.colors)
{
std::cerr << "WARNING: Logging to cerr is enabled, console colors will be disabled" << std::endl;
}
auto cerr_sink = std::make_shared<spdlog::sinks::stderr_sink_mt> ();
global_sinks.push_back (cerr_sink);
}
}
// File setup
if (config.file.enable)
{
// In cases where data_path is not available, file logging should always be disabled
release_assert (data_path);
auto now = std::chrono::system_clock::now ();
auto time = std::chrono::system_clock::to_time_t (now);
auto filename = fmt::format ("log_{:%Y-%m-%d_%H-%M}-{:%S}", fmt::localtime (time), now.time_since_epoch ());
std::replace (filename.begin (), filename.end (), '.', '_'); // Replace millisecond dot separator with underscore
std::filesystem::path log_path{ data_path.value () / "log" / (filename + ".log") };
log_path = std::filesystem::absolute (log_path);
std::cerr << "Logging to file: " << log_path.string () << std::endl;
// If either max_size or rotation_count is 0, then disable file rotation
if (config.file.max_size == 0 || config.file.rotation_count == 0)
{
std::cerr << "WARNING: Log file rotation is disabled, log file size may grow without bound" << std::endl;
auto file_sink = std::make_shared<spdlog::sinks::basic_file_sink_mt> (log_path.string (), true);
global_sinks.push_back (file_sink);
}
else
{
auto file_sink = std::make_shared<spdlog::sinks::rotating_file_sink_mt> (log_path.string (), config.file.max_size, config.file.rotation_count);
global_sinks.push_back (file_sink);
}
}
}
void nano::logger::flush ()
{
for (auto & sink : global_sinks)
{
sink->flush ();
}
}
/*
* logger
*/
nano::logger::logger (std::string identifier) :
identifier{ std::move (identifier) }
{
release_assert (global_initialized, "logging should be initialized before creating a logger");
}
nano::logger::~logger ()
{
flush ();
}
spdlog::logger & nano::logger::get_logger (nano::log::type tag)
{
// This is a two-step process to avoid exclusively locking the mutex in the common case
{
std::shared_lock lock{ mutex };
if (auto it = spd_loggers.find (tag); it != spd_loggers.end ())
{
return *it->second;
}
}
// Not found, create a new logger
{
std::unique_lock lock{ mutex };
auto [it, inserted] = spd_loggers.emplace (tag, make_logger (tag));
return *it->second;
}
}
std::shared_ptr<spdlog::logger> nano::logger::make_logger (nano::log::type tag)
{
auto const & config = global_config;
auto const & sinks = global_sinks;
auto name = global_name_formatter (tag, identifier);
auto spd_logger = std::make_shared<spdlog::logger> (name, sinks.begin (), sinks.end ());
if (auto it = config.levels.find ({ tag, nano::log::detail::all }); it != config.levels.end ())
{
spd_logger->set_level (to_spdlog_level (it->second));
}
else
{
spd_logger->set_level (to_spdlog_level (config.default_level));
}
spd_logger->flush_on (to_spdlog_level (config.flush_level));
return spd_logger;
}
spdlog::level::level_enum nano::logger::to_spdlog_level (nano::log::level level)
{
switch (level)
{
case nano::log::level::off:
return spdlog::level::off;
case nano::log::level::critical:
return spdlog::level::critical;
case nano::log::level::error:
return spdlog::level::err;
case nano::log::level::warn:
return spdlog::level::warn;
case nano::log::level::info:
return spdlog::level::info;
case nano::log::level::debug:
return spdlog::level::debug;
case nano::log::level::trace:
return spdlog::level::trace;
}
debug_assert (false, "Invalid log level");
return spdlog::level::off;
}
/*
* logging config presets
*/
nano::log_config nano::log_config::cli_default ()
{
log_config config{};
config.default_level = nano::log::level::critical;
config.console.to_cerr = true; // Use cerr to avoid interference with CLI output that goes to stdout
config.file.enable = false;
return config;
}
nano::log_config nano::log_config::daemon_default ()
{
log_config config{};
config.default_level = nano::log::level::info;
return config;
}
nano::log_config nano::log_config::tests_default ()
{
log_config config{};
config.default_level = nano::log::level::off;
config.file.enable = false;
return config;
}
nano::log_config nano::log_config::sample_config ()
{
log_config config{};
config.default_level = nano::log::level::info;
config.levels = default_levels (nano::log::level::info); // Populate with default levels
return config;
}
/*
* logging config
*/
nano::error nano::log_config::serialize_toml (nano::tomlconfig & toml) const
{
nano::tomlconfig config_toml;
serialize (config_toml);
toml.put_child ("log", config_toml);
return toml.get_error ();
}
nano::error nano::log_config::deserialize_toml (nano::tomlconfig & toml)
{
try
{
auto logging_l = toml.get_optional_child ("log");
if (logging_l)
{
deserialize (*logging_l);
}
}
catch (std::invalid_argument const & ex)
{
toml.get_error ().set (ex.what ());
}
return toml.get_error ();
}
void nano::log_config::serialize (nano::tomlconfig & toml) const
{
toml.put ("default_level", std::string{ to_string (default_level) });
nano::tomlconfig console_config;
console_config.put ("enable", console.enable);
console_config.put ("to_cerr", console.to_cerr);
console_config.put ("colors", console.colors);
toml.put_child ("console", console_config);
nano::tomlconfig file_config;
file_config.put ("enable", file.enable);
file_config.put ("max_size", file.max_size);
file_config.put ("rotation_count", file.rotation_count);
toml.put_child ("file", file_config);
nano::tomlconfig levels_config;
for (auto const & [logger_id, level] : levels)
{
auto logger_name = to_string (logger_id.first);
levels_config.put (std::string{ logger_name }, std::string{ to_string (level) });
}
toml.put_child ("levels", levels_config);
}
void nano::log_config::deserialize (nano::tomlconfig & toml)
{
if (toml.has_key ("default_level"))
{
auto default_level_l = toml.get<std::string> ("default_level");
default_level = nano::log::parse_level (default_level_l);
}
if (toml.has_key ("console"))
{
auto console_config = toml.get_required_child ("console");
console_config.get ("enable", console.enable);
console_config.get ("to_cerr", console.to_cerr);
console_config.get ("colors", console.colors);
}
if (toml.has_key ("file"))
{
auto file_config = toml.get_required_child ("file");
file_config.get ("enable", file.enable);
file_config.get ("max_size", file.max_size);
file_config.get ("rotation_count", file.rotation_count);
}
if (toml.has_key ("levels"))
{
auto levels_config = toml.get_required_child ("levels");
for (auto & level : levels_config.get_values<std::string> ())
{
try
{
auto & [name_str, level_str] = level;
auto logger_level = nano::log::parse_level (level_str);
auto logger_id = parse_logger_id (name_str);
levels[logger_id] = logger_level;
}
catch (std::invalid_argument const & ex)
{
// Ignore but warn about invalid logger names
std::cerr << "Problem processing log config: " << ex.what () << std::endl;
}
}
}
}
/**
* Parse `logger_name[:logger_detail]` into a pair of `log::type` and `log::detail`
* @throw std::invalid_argument if `logger_name` or `logger_detail` are invalid
*/
nano::log_config::logger_id_t nano::log_config::parse_logger_id (const std::string & logger_name)
{
auto pos = logger_name.find ("::");
if (pos == std::string::npos)
{
return { nano::log::parse_type (logger_name), nano::log::detail::all };
}
else
{
auto logger_type = logger_name.substr (0, pos);
auto logger_detail = logger_name.substr (pos + 1);
return { nano::log::parse_type (logger_type), nano::log::parse_detail (logger_detail) };
}
}
std::map<nano::log_config::logger_id_t, nano::log::level> nano::log_config::default_levels (nano::log::level default_level)
{
std::map<nano::log_config::logger_id_t, nano::log::level> result;
for (auto const & type : nano::log::all_types ())
{
result.emplace (std::make_pair (type, nano::log::detail::all), default_level);
}
return result;
}
/*
* config loading
*/
// Using std::cerr here, since logging may not be initialized yet
nano::log_config nano::load_log_config (nano::log_config fallback, const std::filesystem::path & data_path, const std::vector<std::string> & config_overrides)
{
const std::string config_filename = "config-log.toml";
try
{
auto config = nano::load_config_file<nano::log_config> (fallback, config_filename, data_path, config_overrides);
// Parse default log level from environment variable, e.g. "NANO_LOG=debug"
auto env_level = nano::get_env ("NANO_LOG");
if (env_level)
{
try
{
config.default_level = nano::log::parse_level (*env_level);
std::cerr << "Using default log level from NANO_LOG environment variable: " << *env_level << std::endl;
}
catch (std::invalid_argument const & ex)
{
std::cerr << "Invalid log level from NANO_LOG environment variable: " << ex.what () << std::endl;
}
}
// Parse per logger levels from environment variable, e.g. "NANO_LOG_LEVELS=ledger=debug,node=trace"
auto env_levels = nano::get_env ("NANO_LOG_LEVELS");
if (env_levels)
{
std::map<nano::log_config::logger_id_t, nano::log::level> levels;
for (auto const & env_level_str : nano::util::split (*env_levels, ','))
{
try
{
// Split 'logger_name=level' into a pair of 'logger_name' and 'level'
auto arr = nano::util::split (env_level_str, '=');
if (arr.size () != 2)
{
throw std::invalid_argument ("Invalid entry: " + env_level_str);
}
auto name_str = arr[0];
auto level_str = arr[1];
auto logger_id = nano::log_config::parse_logger_id (name_str);
auto logger_level = nano::log::parse_level (level_str);
levels[logger_id] = logger_level;
std::cerr << "Using logger log level from NANO_LOG_LEVELS environment variable: " << name_str << "=" << level_str << std::endl;
}
catch (std::invalid_argument const & ex)
{
std::cerr << "Invalid log level from NANO_LOG_LEVELS environment variable: " << ex.what () << std::endl;
}
}
// Merge with existing levels
for (auto const & [logger_id, level] : levels)
{
config.levels[logger_id] = level;
}
}
return config;
}
catch (std::runtime_error const & ex)
{
std::cerr << "Unable to load log config. Using defaults. Error: " << ex.what () << std::endl;
}
return fallback;
}

141
nano/lib/logging.hpp Normal file
View file

@ -0,0 +1,141 @@
#pragma once
#include <nano/lib/logging_enums.hpp>
#include <nano/lib/tomlconfig.hpp>
#include <initializer_list>
#include <memory>
#include <shared_mutex>
#include <sstream>
#include <spdlog/spdlog.h>
namespace nano
{
class log_config final
{
public:
nano::error serialize_toml (nano::tomlconfig &) const;
nano::error deserialize_toml (nano::tomlconfig &);
private:
void serialize (nano::tomlconfig &) const;
void deserialize (nano::tomlconfig &);
public:
nano::log::level default_level{ nano::log::level::info };
nano::log::level flush_level{ nano::log::level::error };
using logger_id_t = std::pair<nano::log::type, nano::log::detail>;
std::map<logger_id_t, nano::log::level> levels;
struct console_config
{
bool enable{ true };
bool colors{ true };
bool to_cerr{ false };
};
struct file_config
{
bool enable{ true };
std::size_t max_size{ 32 * 1024 * 1024 };
std::size_t rotation_count{ 4 };
};
console_config console;
file_config file;
public: // Predefined defaults
static log_config cli_default ();
static log_config daemon_default ();
static log_config tests_default ();
static log_config sample_config (); // For auto-generated sample config files
static logger_id_t parse_logger_id (std::string const &);
private:
/// Returns placeholder log levels for all loggers
static std::map<logger_id_t, nano::log::level> default_levels (nano::log::level);
};
nano::log_config load_log_config (nano::log_config fallback, std::filesystem::path const & data_path, std::vector<std::string> const & config_overrides = {});
class logger final
{
public:
explicit logger (std::string identifier = "");
~logger ();
// Disallow copies
logger (logger const &) = delete;
public:
static void initialize (nano::log_config fallback, std::optional<std::filesystem::path> data_path = std::nullopt, std::vector<std::string> const & config_overrides = std::vector<std::string> ());
static void initialize_for_tests (nano::log_config fallback);
static void flush ();
private:
static bool global_initialized;
static nano::log_config global_config;
static std::vector<spdlog::sink_ptr> global_sinks;
static std::function<std::string (nano::log::type tag, std::string identifier)> global_name_formatter;
static void initialize_common (nano::log_config const &, std::optional<std::filesystem::path> data_path);
public:
template <class... Args>
void log (nano::log::level level, nano::log::type tag, spdlog::format_string_t<Args...> fmt, Args &&... args)
{
get_logger (tag).log (to_spdlog_level (level), fmt, std::forward<Args> (args)...);
}
template <class... Args>
void debug (nano::log::type tag, spdlog::format_string_t<Args...> fmt, Args &&... args)
{
get_logger (tag).debug (fmt, std::forward<Args> (args)...);
}
template <class... Args>
void info (nano::log::type tag, spdlog::format_string_t<Args...> fmt, Args &&... args)
{
get_logger (tag).info (fmt, std::forward<Args> (args)...);
}
template <class... Args>
void warn (nano::log::type tag, spdlog::format_string_t<Args...> fmt, Args &&... args)
{
get_logger (tag).warn (fmt, std::forward<Args> (args)...);
}
template <class... Args>
void error (nano::log::type tag, spdlog::format_string_t<Args...> fmt, Args &&... args)
{
get_logger (tag).error (fmt, std::forward<Args> (args)...);
}
template <class... Args>
void critical (nano::log::type tag, spdlog::format_string_t<Args...> fmt, Args &&... args)
{
get_logger (tag).critical (fmt, std::forward<Args> (args)...);
}
private:
const std::string identifier;
std::unordered_map<nano::log::type, std::shared_ptr<spdlog::logger>> spd_loggers;
std::shared_mutex mutex;
private:
spdlog::logger & get_logger (nano::log::type tag);
std::shared_ptr<spdlog::logger> make_logger (nano::log::type tag);
static spdlog::level::level_enum to_spdlog_level (nano::log::level);
};
/**
* Returns a logger instance that can be used before node specific logging is available.
* Should only be used for logging that happens during startup and initialization, since it won't contain node specific identifier.
*/
nano::logger & default_logger ();
}

View file

@ -0,0 +1,91 @@
#define MAGIC_ENUM_RANGE_MIN 0
#define MAGIC_ENUM_RANGE_MAX 256
#include <nano/lib/logging_enums.hpp>
#include <nano/lib/utility.hpp>
#include <magic_enum.hpp>
std::string_view nano::log::to_string (nano::log::type tag)
{
return magic_enum::enum_name (tag);
}
std::string_view nano::log::to_string (nano::log::detail detail)
{
return magic_enum::enum_name (detail);
}
std::string_view nano::log::to_string (nano::log::level level)
{
return magic_enum::enum_name (level);
}
const std::vector<nano::log::level> & nano::log::all_levels ()
{
static std::vector<nano::log::level> all = [] () {
std::vector<nano::log::level> result;
for (auto const & lvl : magic_enum::enum_values<nano::log::level> ())
{
result.push_back (lvl);
}
return result;
}();
return all;
}
const std::vector<nano::log::type> & nano::log::all_types ()
{
static std::vector<nano::log::type> all = [] () {
std::vector<nano::log::type> result;
for (auto const & lvl : magic_enum::enum_values<nano::log::type> ())
{
result.push_back (lvl);
}
return result;
}();
return all;
}
nano::log::level nano::log::parse_level (std::string_view name)
{
auto value = magic_enum::enum_cast<nano::log::level> (name);
if (value.has_value ())
{
return value.value ();
}
else
{
auto all_levels_str = nano::util::join (nano::log::all_levels (), ", ", [] (auto const & lvl) {
return to_string (lvl);
});
throw std::invalid_argument ("Invalid log level: " + std::string (name) + ". Must be one of: " + all_levels_str);
}
}
nano::log::type nano::log::parse_type (std::string_view name)
{
auto value = magic_enum::enum_cast<nano::log::type> (name);
if (value.has_value ())
{
return value.value ();
}
else
{
throw std::invalid_argument ("Invalid log type: " + std::string (name));
}
}
nano::log::detail nano::log::parse_detail (std::string_view name)
{
auto value = magic_enum::enum_cast<nano::log::detail> (name);
if (value.has_value ())
{
return value.value ();
}
else
{
throw std::invalid_argument ("Invalid log detail: " + std::string (name));
}
}

142
nano/lib/logging_enums.hpp Normal file
View file

@ -0,0 +1,142 @@
#pragma once
#include <cstdint>
#include <string_view>
#include <vector>
namespace nano::log
{
enum class level
{
trace,
debug,
info,
warn,
error,
critical,
off,
};
enum class type
{
all = 0, // reserved
generic,
init,
config,
logging,
node,
node_wrapper,
daemon,
daemon_rpc,
daemon_wallet,
wallet,
qt,
rpc,
rpc_connection,
rpc_callbacks,
rpc_request,
ipc,
ipc_server,
websocket,
tls,
active_transactions,
election,
blockprocessor,
network,
channel,
socket,
socket_server,
tcp,
tcp_server,
tcp_listener,
prunning,
conf_processor_bounded,
conf_processor_unbounded,
distributed_work,
epoch_upgrader,
opencl_work,
upnp,
repcrawler,
lmdb,
rocksdb,
txn_tracker,
gap_cache,
vote_processor,
bulk_pull_client,
bulk_pull_server,
bulk_pull_account_client,
bulk_pull_account_server,
bulk_push_client,
bulk_push_server,
frontier_req_client,
frontier_req_server,
bootstrap,
bootstrap_lazy,
bootstrap_legacy,
};
enum class detail
{
all = 0, // reserved
// node
process_confirmed,
// active_transactions
active_started,
active_stopped,
// election
election_confirmed,
election_expired,
// blockprocessor
block_processed,
// vote_processor
vote_processed,
// network
message_received,
message_sent,
message_dropped,
// bulk pull/push
pulled_block,
sending_block,
sending_pending,
sending_frontier,
requesting_account_or_head,
requesting_pending,
};
// TODO: Additionally categorize logs by categories which can be enabled/disabled independently
enum class category
{
all = 0, // reserved
work_generation,
// ...
};
}
namespace nano::log
{
std::string_view to_string (nano::log::type);
std::string_view to_string (nano::log::detail);
std::string_view to_string (nano::log::level);
/// @throw std::invalid_argument if the input string does not match a log::level
nano::log::level parse_level (std::string_view);
/// @throw std::invalid_argument if the input string does not match a log::type
nano::log::type parse_type (std::string_view);
/// @throw std::invalid_argument if the input string does not match a log::detail
nano::log::detail parse_detail (std::string_view);
std::vector<nano::log::level> const & all_levels ();
std::vector<nano::log::type> const & all_types ();
}

View file

@ -894,6 +894,27 @@ std::string nano::to_string (double const value_a, int const precision_a)
return stream.str ();
}
std::ostream & nano::operator<< (std::ostream & os, const uint128_union & val)
{
// TODO: Replace with streaming implementation
os << val.to_string ();
return os;
}
std::ostream & nano::operator<< (std::ostream & os, const uint256_union & val)
{
// TODO: Replace with streaming implementation
os << val.to_string ();
return os;
}
std::ostream & nano::operator<< (std::ostream & os, const uint512_union & val)
{
// TODO: Replace with streaming implementation
os << val.to_string ();
return os;
}
#ifdef _WIN32
#pragma warning(push)
#pragma warning(disable : 4146) // warning C4146: unary minus operator applied to unsigned type, result still unsigned

View file

@ -4,6 +4,7 @@
#include <boost/multiprecision/cpp_int.hpp>
#include <array>
#include <ostream>
namespace nano
{
@ -61,6 +62,7 @@ public:
using uint128_union::uint128_union;
};
class raw_key;
class uint256_union
{
public:
@ -265,6 +267,11 @@ std::string to_string_hex (uint64_t const);
std::string to_string_hex (uint16_t const);
bool from_string_hex (std::string const &, uint64_t &);
/* Printing adapters */
std::ostream & operator<< (std::ostream & os, const uint128_union & val);
std::ostream & operator<< (std::ostream & os, const uint256_union & val);
std::ostream & operator<< (std::ostream & os, const uint512_union & val);
/**
* Convert a double to string in fixed format
* @param precision_a (optional) use a specific precision (default is the maximum)

View file

@ -21,6 +21,8 @@ enum class type : uint8_t
http_callback,
ipc,
tcp,
channel,
socket,
confirmation_height,
confirmation_observer,
drop,
@ -311,7 +313,7 @@ enum class dir : uint8_t
namespace nano
{
std::string_view to_string (stat::type type);
std::string_view to_string (stat::detail detail);
std::string_view to_string (stat::dir dir);
std::string_view to_string (stat::type);
std::string_view to_string (stat::detail);
std::string_view to_string (stat::dir);
}

View file

@ -1,5 +1,5 @@
#include <nano/lib/config.hpp>
#include <nano/lib/logger_mt.hpp>
#include <nano/lib/logging.hpp>
#include <nano/lib/tlsconfig.hpp>
#include <nano/lib/tomlconfig.hpp>
@ -138,7 +138,7 @@ namespace
}
#endif
nano::error read_tls_config_toml (std::filesystem::path const & data_path_a, nano::tls_config & config_a, nano::logger_mt & logger_a, std::vector<std::string> const & config_overrides)
nano::error read_tls_config_toml (std::filesystem::path const & data_path_a, nano::tls_config & config_a, nano::logger & logger, std::vector<std::string> const & config_overrides)
{
nano::error error;
auto toml_config_path = nano::get_tls_toml_config_path (data_path_a);
@ -176,9 +176,7 @@ nano::error read_tls_config_toml (std::filesystem::path const & data_path_a, nan
#ifdef NANO_SECURE_RPC
load_certs (config_a, logger_a);
#else
auto msg ("https or wss is enabled in the TLS configuration, but the node is not built with NANO_SECURE_RPC");
std::cerr << msg << std::endl;
logger_a.always_log (msg);
logger.critical (nano::log::type::tls, "HTTPS or WSS is enabled in the TLS configuration, but the node is not built with NANO_SECURE_RPC");
std::exit (1);
#endif
}

View file

@ -13,7 +13,7 @@
namespace nano
{
class logger_mt;
class logger;
class jsonconfig;
class tomlconfig;
@ -54,5 +54,5 @@ public:
#endif
};
nano::error read_tls_config_toml (std::filesystem::path const & data_path_a, nano::tls_config & config_a, nano::logger_mt & logger_a, std::vector<std::string> const & config_overrides = std::vector<std::string> ());
nano::error read_tls_config_toml (std::filesystem::path const & data_path_a, nano::tls_config & config_a, nano::logger &, std::vector<std::string> const & config_overrides = std::vector<std::string> ());
}

View file

@ -171,6 +171,19 @@ public:
return *this;
}
template <typename T>
std::vector<std::pair<std::string, T>> get_values ()
{
std::vector<std::pair<std::string, T>> result;
for (auto & entry : *tree)
{
T target{};
get_config (true, entry.first, target, target);
result.push_back ({ entry.first, target });
}
return result;
}
protected:
template <typename T, typename = std::enable_if_t<nano::is_lexical_castable<T>::value>>
tomlconfig & get_config (bool optional, std::string const & key, T & target, T default_value = T ())

View file

@ -3,6 +3,7 @@
#include <nano/lib/locks.hpp>
#include <boost/current_function.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/preprocessor/facilities/empty.hpp>
#include <boost/preprocessor/facilities/overload.hpp>
@ -10,6 +11,7 @@
#include <filesystem>
#include <functional>
#include <mutex>
#include <sstream>
#include <vector>
#include <magic_enum_containers.hpp>
@ -210,3 +212,54 @@ bool elapsed (nano::clock::time_point const & last, Duration duration)
return elapsed (last, duration, nano::clock::now ());
}
}
namespace nano::util
{
/**
* Joins elements with specified delimiter while transforming those elements via specified transform function
*/
template <class InputIt, class Func>
std::string join (InputIt first, InputIt last, std::string_view delimiter, Func transform)
{
bool start = true;
std::stringstream ss;
while (first != last)
{
if (start)
{
start = false;
}
else
{
ss << delimiter << " ";
}
ss << transform (*first);
++first;
}
return ss.str ();
}
template <class Container, class Func>
std::string join (Container const & container, std::string_view delimiter, Func transform)
{
return join (container.begin (), container.end (), delimiter, transform);
}
inline std::vector<std::string> split (const std::string & str, char delimiter)
{
std::stringstream ss{ str };
std::vector<std::string> result;
std::string item;
while (std::getline (ss, item, delimiter))
{
result.push_back (item);
}
return result;
}
template <class T>
std::string to_str (T const & val)
{
return boost::lexical_cast<std::string> (val);
}
}

View file

@ -3,5 +3,4 @@ add_executable(load_test entry.cpp)
target_link_libraries(load_test test_common Boost::process)
include_directories(${CMAKE_SOURCE_DIR}/submodules)
include_directories(${CMAKE_SOURCE_DIR}/submodules/cpptoml/include)
include_directories(${CMAKE_SOURCE_DIR}/submodules/gtest/googletest/include)

View file

@ -4,6 +4,7 @@
#include <nano/boost/beast/core/flat_buffer.hpp>
#include <nano/boost/beast/http.hpp>
#include <nano/boost/process/child.hpp>
#include <nano/lib/logging.hpp>
#include <nano/lib/thread_runner.hpp>
#include <nano/lib/threading.hpp>
#include <nano/lib/tomlconfig.hpp>
@ -490,6 +491,7 @@ account_info account_info_rpc (boost::asio::io_context & ioc, tcp::resolver::res
/** This launches a node and fires a lot of send/recieve RPC requests at it (configurable), then other nodes are tested to make sure they observe these blocks as well. */
int main (int argc, char * const * argv)
{
nano::logger::initialize_for_tests (nano::log_config::tests_default ());
nano::force_nano_dev_network ();
boost::program_options::options_description description ("Command line options");

View file

@ -18,7 +18,9 @@ add_custom_command(
COMMAND nano_node --generate_config node >
${PROJECT_BINARY_DIR}/config-node.toml.sample
COMMAND nano_node --generate_config rpc >
${PROJECT_BINARY_DIR}/config-rpc.toml.sample)
${PROJECT_BINARY_DIR}/config-rpc.toml.sample
COMMAND nano_node --generate_config log >
${PROJECT_BINARY_DIR}/config-log.toml.sample)
if((NANO_GUI OR RAIBLOCKS_GUI) AND NOT APPLE)
if(WIN32)

View file

@ -20,6 +20,8 @@
#include <csignal>
#include <iostream>
#include <fmt/chrono.h>
namespace
{
void nano_abort_signal_handler (int signum)
@ -59,27 +61,31 @@ volatile sig_atomic_t sig_int_or_term = 0;
constexpr std::size_t OPEN_FILE_DESCRIPTORS_LIMIT = 16384;
}
void nano_daemon::daemon::run (std::filesystem::path const & data_path, nano::node_flags const & flags)
void nano::daemon::run (std::filesystem::path const & data_path, nano::node_flags const & flags)
{
nano::logger::initialize (nano::log_config::daemon_default (), data_path, flags.config_overrides);
logger.info (nano::log::type::daemon, "Daemon started");
install_abort_signal_handler ();
std::filesystem::create_directories (data_path);
boost::system::error_code error_chmod;
nano::set_secure_perm_directory (data_path, error_chmod);
std::unique_ptr<nano::thread_runner> runner;
nano::network_params network_params{ nano::network_constants::active_network };
nano::daemon_config config{ data_path, network_params };
auto error = nano::read_node_config_toml (data_path, config, flags.config_overrides);
nano::set_use_memory_pools (config.node.use_memory_pools);
if (!error)
{
error = nano::flags_config_conflicts (flags, config.node);
}
if (!error)
{
config.node.logging.init (data_path);
nano::logger_mt logger{ config.node.logging.min_time_between_log_output };
auto tls_config (std::make_shared<nano::tls_config> ());
error = nano::read_tls_config_toml (data_path, *tls_config, logger);
if (error)
@ -100,23 +106,18 @@ void nano_daemon::daemon::run (std::filesystem::path const & data_path, nano::no
: std::function<boost::optional<uint64_t> (nano::work_version const, nano::root const &, uint64_t, std::atomic<int> &)> (nullptr));
try
{
// This avoid a blank prompt during any node initialization delays
auto initialization_text = "Starting up Nano node...";
std::cout << initialization_text << std::endl;
logger.always_log (initialization_text);
// This avoids a blank prompt during any node initialization delays
logger.info (nano::log::type::daemon, "Starting up Nano node...");
// Print info about number of logical cores detected, those are used to decide how many IO, worker and signature checker threads to spawn
logger.always_log (boost::format ("Hardware concurrency: %1% ( configured: %2% )") % std::thread::hardware_concurrency () % nano::hardware_concurrency ());
logger.info (nano::log::type::daemon, "Hardware concurrency: {} ( configured: {} )", std::thread::hardware_concurrency (), nano::hardware_concurrency ());
nano::set_file_descriptor_limit (OPEN_FILE_DESCRIPTORS_LIMIT);
auto const file_descriptor_limit = nano::get_file_descriptor_limit ();
logger.info (nano::log::type::daemon, "File descriptors limit: {}", file_descriptor_limit);
if (file_descriptor_limit < OPEN_FILE_DESCRIPTORS_LIMIT)
{
logger.always_log (boost::format ("WARNING: open file descriptors limit is %1%, lower than the %2% recommended. Node was unable to change it.") % file_descriptor_limit % OPEN_FILE_DESCRIPTORS_LIMIT);
}
else
{
logger.always_log (boost::format ("Open file descriptors limit is %1%") % file_descriptor_limit);
logger.warn (nano::log::type::daemon, "File descriptors limit is lower than the {} recommended. Node was unable to change it.", OPEN_FILE_DESCRIPTORS_LIMIT);
}
// for the daemon start up, if the user hasn't specified a port in
@ -133,18 +134,15 @@ void nano_daemon::daemon::run (std::filesystem::path const & data_path, nano::no
auto network_label = node->network_params.network.get_current_network_as_string ();
std::time_t dateTime = std::time (nullptr);
std::cout << "Network: " << network_label << ", version: " << NANO_VERSION_STRING << "\n"
<< "Path: " << node->application_path.string () << "\n"
<< "Build Info: " << BUILD_INFO << "\n"
<< "Database backend: " << node->store.vendor_get () << "\n"
<< "Start time: " << std::put_time (std::gmtime (&dateTime), "%c UTC") << std::endl;
logger.info (nano::log::type::daemon, "Network: {}", network_label);
logger.info (nano::log::type::daemon, "Version: {}", NANO_VERSION_STRING);
logger.info (nano::log::type::daemon, "Data path: '{}'", node->application_path.string ());
logger.info (nano::log::type::daemon, "Build info: {}", BUILD_INFO);
logger.info (nano::log::type::daemon, "Database backend: {}", node->store.vendor_get ());
logger.info (nano::log::type::daemon, "Start time: {:%c} UTC", fmt::gmtime (dateTime));
auto voting (node->wallets.reps ().voting);
if (voting > 1)
{
std::cout << "Voting with more than one representative can limit performance: " << voting << " representatives are configured" << std::endl;
}
node->start ();
nano::ipc::ipc_server ipc_server (*node, config.rpc);
std::unique_ptr<boost::process::child> rpc_process;
std::unique_ptr<nano::rpc> rpc;
@ -187,7 +185,9 @@ void nano_daemon::daemon::run (std::filesystem::path const & data_path, nano::no
}
debug_assert (!nano::signal_handler_impl);
nano::signal_handler_impl = [&io_ctx] () {
nano::signal_handler_impl = [this, &io_ctx] () {
logger.warn (nano::log::type::daemon, "Interrupt signal received, stopping...");
io_ctx.stop ();
sig_int_or_term = 1;
};
@ -219,16 +219,18 @@ void nano_daemon::daemon::run (std::filesystem::path const & data_path, nano::no
}
else
{
std::cerr << "Error initializing node\n";
logger.critical (nano::log::type::daemon, "Error initializing node");
}
}
catch (std::runtime_error const & e)
{
std::cerr << "Error while running node (" << e.what () << ")\n";
logger.critical (nano::log::type::daemon, "Error while running node: {}", e.what ());
}
}
else
{
std::cerr << "Error deserializing config: " << error.get_message () << std::endl;
logger.critical (nano::log::type::daemon, "Error deserializing config: {}", error.get_message ());
}
logger.info (nano::log::type::daemon, "Daemon exiting");
}

View file

@ -1,11 +1,13 @@
#include <nano/lib/logging.hpp>
namespace nano
{
class node_flags;
}
namespace nano_daemon
{
class daemon
{
nano::logger logger{ "daemon" };
public:
void run (std::filesystem::path const &, nano::node_flags const & flags);
};

View file

@ -53,8 +53,11 @@ public:
int main (int argc, char * const * argv)
{
nano::set_umask ();
nano::set_umask (); // Make sure the process umask is set before any files are created
nano::logger::initialize (nano::log_config::cli_default ());
nano::node_singleton_memory_pool_purge_guard memory_pool_cleanup_guard;
boost::program_options::options_description description ("Command line options");
// clang-format off
description.add_options ()
@ -138,7 +141,7 @@ int main (int argc, char * const * argv)
{
if (vm.count ("daemon") > 0)
{
nano_daemon::daemon daemon;
nano::daemon daemon;
nano::node_flags flags;
auto flags_ec = nano::update_flags (flags, vm);
if (flags_ec)
@ -281,14 +284,14 @@ int main (int argc, char * const * argv)
{
if (sample.diff > log_threshold)
{
node->logger.always_log (sample.get_entry ());
std::cout << '\t' << sample.get_entry () << '\n';
}
}
for (auto const & newcomer : newcomers)
{
if (newcomer.second > log_threshold)
{
node->logger.always_log (newcomer_entry (newcomer));
std::cout << '\t' << newcomer_entry (newcomer) << '\n';
}
}
}
@ -610,7 +613,7 @@ int main (int argc, char * const * argv)
error |= device >= environment.platforms[platform].devices.size ();
if (!error)
{
nano::logger_mt logger;
nano::logger logger;
nano::opencl_config config (platform, device, threads);
auto opencl (nano::opencl_work::create (true, config, logger, network_params.work));
nano::work_pool work_pool{ network_params.network, 0, std::chrono::nanoseconds (0), opencl ? [&opencl] (nano::work_version const version_a, nano::root const & root_a, uint64_t difficulty_a, std::atomic<int> &) {
@ -1121,10 +1124,8 @@ int main (int argc, char * const * argv)
boost::asio::io_context io_ctx1;
boost::asio::io_context io_ctx2;
nano::work_pool work{ network_params.network, std::numeric_limits<unsigned>::max () };
nano::logging logging;
auto path1 (nano::unique_path ());
auto path2 (nano::unique_path ());
logging.init (path1);
std::vector<std::string> config_overrides;
auto config (vm.find ("config"));
if (config != vm.end ())
@ -1871,7 +1872,7 @@ int main (int argc, char * const * argv)
nano::update_flags (node_flags, vm);
nano::inactive_node inactive_node (data_path, node_flags);
auto node = inactive_node.node;
node->ledger_pruning (node_flags.block_processor_batch_size != 0 ? node_flags.block_processor_batch_size : 16 * 1024, true, true);
node->ledger_pruning (node_flags.block_processor_batch_size != 0 ? node_flags.block_processor_batch_size : 16 * 1024, true);
}
else if (vm.count ("debug_stacktrace"))
{
@ -1879,15 +1880,12 @@ int main (int argc, char * const * argv)
}
else if (vm.count ("debug_sys_logging"))
{
#ifdef BOOST_WINDOWS
if (!nano::event_log_reg_entry_exists () && !nano::is_windows_elevated ())
{
std::cerr << "The event log requires the HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\EventLog\\Nano\\Nano registry entry, run again as administator to create it.\n";
return 1;
}
#endif
auto inactive_node = nano::default_inactive_node (data_path, vm);
inactive_node->node->logger.always_log (nano::severity_level::error, "Testing system logger");
inactive_node->node->logger.critical ({}, "Testing system logger (CRITICAL)");
inactive_node->node->logger.error ({}, "Testing system logger (ERROR)");
inactive_node->node->logger.warn ({}, "Testing system logger (WARN)");
inactive_node->node->logger.info ({}, "Testing system logger (INFO)");
inactive_node->node->logger.debug ({}, "Testing system logger (DEBUG)");
}
else if (vm.count ("debug_account_versions"))
{

View file

@ -1,5 +1,6 @@
#include <nano/lib/cli.hpp>
#include <nano/lib/errors.hpp>
#include <nano/lib/logging.hpp>
#include <nano/lib/signal_manager.hpp>
#include <nano/lib/thread_runner.hpp>
#include <nano/lib/threading.hpp>
@ -11,34 +12,24 @@
#include <nano/rpc/rpc_request_processor.hpp>
#include <nano/secure/utility.hpp>
#include <boost/log/utility/setup/common_attributes.hpp>
#include <boost/log/utility/setup/file.hpp>
#include <boost/filesystem.hpp>
#include <boost/program_options.hpp>
namespace
{
void logging_init (std::filesystem::path const & application_path_a)
{
static std::atomic_flag logging_already_added = ATOMIC_FLAG_INIT;
if (!logging_already_added.test_and_set ())
{
boost::log::add_common_attributes ();
auto path = application_path_a / "log";
uintmax_t max_size{ 128 * 1024 * 1024 };
uintmax_t rotation_size{ 4 * 1024 * 1024 };
bool flush{ true };
boost::log::add_file_log (boost::log::keywords::target = path, boost::log::keywords::file_name = path / "rpc_log_%Y-%m-%d_%H-%M-%S.%N.log", boost::log::keywords::rotation_size = rotation_size, boost::log::keywords::auto_flush = flush, boost::log::keywords::scan_method = boost::log::sinks::file::scan_method::scan_matching, boost::log::keywords::max_size = max_size, boost::log::keywords::format = "[%TimeStamp%]: %Message%");
}
}
volatile sig_atomic_t sig_int_or_term = 0;
nano::logger logger{ "rpc_daemon" };
void run (std::filesystem::path const & data_path, std::vector<std::string> const & config_overrides)
{
logger.info (nano::log::type::daemon_rpc, "Daemon started (RPC)");
std::filesystem::create_directories (data_path);
boost::system::error_code error_chmod;
nano::set_secure_perm_directory (data_path, error_chmod);
std::unique_ptr<nano::thread_runner> runner;
nano::network_params network_params{ nano::network_constants::active_network };
@ -46,14 +37,11 @@ void run (std::filesystem::path const & data_path, std::vector<std::string> cons
auto error = nano::read_rpc_config_toml (data_path, rpc_config, config_overrides);
if (!error)
{
logging_init (data_path);
nano::logger_mt logger;
auto tls_config (std::make_shared<nano::tls_config> ());
error = nano::read_tls_config_toml (data_path, *tls_config, logger);
if (error)
{
std::cerr << error.get_message () << std::endl;
logger.critical (nano::log::type::daemon, "Error reading RPC TLS config: {}", error.get_message ());
std::exit (1);
}
else
@ -88,19 +76,22 @@ void run (std::filesystem::path const & data_path, std::vector<std::string> cons
}
catch (std::runtime_error const & e)
{
std::cerr << "Error while running rpc (" << e.what () << ")\n";
logger.critical (nano::log::type::daemon, "Error while running RPC: {}", e.what ());
}
}
else
{
std::cerr << "Error deserializing config: " << error.get_message () << std::endl;
logger.critical (nano::log::type::daemon, "Error deserializing config: {}", error.get_message ());
}
logger.info (nano::log::type::daemon_rpc, "Daemon stopped (RPC)");
}
}
int main (int argc, char * const * argv)
{
nano::set_umask ();
nano::set_umask (); // Make sure the process umask is set before any files are created
nano::logger::initialize (nano::log_config::cli_default ());
boost::program_options::options_description description ("Command line options");

View file

@ -2,6 +2,7 @@
#include <nano/crypto_lib/random_pool.hpp>
#include <nano/lib/cli.hpp>
#include <nano/lib/errors.hpp>
#include <nano/lib/logging.hpp>
#include <nano/lib/rpcconfig.hpp>
#include <nano/lib/thread_runner.hpp>
#include <nano/lib/tlsconfig.hpp>
@ -25,13 +26,18 @@
namespace
{
nano::logger logger{ "wallet_daemon" };
void show_error (std::string const & message_a)
{
logger.critical (nano::log::type::daemon, "{}", message_a);
QMessageBox message (QMessageBox::Critical, "Error starting Nano", message_a.c_str ());
message.setModal (true);
message.show ();
message.exec ();
}
void show_help (std::string const & message_a)
{
QMessageBox message (QMessageBox::NoIcon, "Help", "see <a href=\"https://docs.nano.org/commands/command-line-interface/#launch-options\">launch options</a> ");
@ -68,6 +74,10 @@ nano::error read_wallet_config (nano::wallet_config & config_a, std::filesystem:
int run_wallet (QApplication & application, int argc, char * const * argv, std::filesystem::path const & data_path, nano::node_flags const & flags)
{
nano::logger::initialize (nano::log_config::daemon_default (), data_path, flags.config_overrides);
logger.info (nano::log::type::daemon_wallet, "Daemon started (wallet)");
int result (0);
nano_qt::eventloop_processor processor;
boost::system::error_code error_chmod;
@ -99,9 +109,6 @@ int run_wallet (QApplication & application, int argc, char * const * argv, std::
{
nano::set_use_memory_pools (config.node.use_memory_pools);
config.node.logging.init (data_path);
nano::logger_mt logger{ config.node.logging.min_time_between_log_output };
auto tls_config (std::make_shared<nano::tls_config> ());
error = nano::read_tls_config_toml (data_path, *tls_config, logger);
if (error)
@ -231,12 +238,17 @@ int run_wallet (QApplication & application, int argc, char * const * argv, std::
splash->hide ();
show_error ("Error deserializing config: " + error.get_message ());
}
logger.info (nano::log::type::daemon_wallet, "Daemon exiting (wallet)");
return result;
}
int main (int argc, char * const * argv)
{
nano::set_umask ();
nano::set_umask (); // Make sure the process umask is set before any files are created
nano::logger::initialize (nano::log_config::cli_default ());
nano::node_singleton_memory_pool_purge_guard memory_pool_cleanup_guard;
QApplication application (argc, const_cast<char **> (argv));

View file

@ -110,8 +110,6 @@ add_library(
ipc/ipc_server.cpp
json_handler.hpp
json_handler.cpp
logging.hpp
logging.cpp
make_store.hpp
make_store.cpp
network.hpp
@ -204,8 +202,6 @@ target_link_libraries(
argon2
lmdb
Boost::beast
Boost::log_setup
Boost::log
Boost::program_options
Boost::stacktrace
Boost::system
@ -223,6 +219,5 @@ target_compile_definitions(
add_dependencies(node ipc_flatbuffers_lib)
include_directories(${CMAKE_SOURCE_DIR}/submodules)
include_directories(${CMAKE_SOURCE_DIR}/submodules/cpptoml/include)
include_directories(
${CMAKE_SOURCE_DIR}/submodules/nano-pow-server/deps/cpptoml/include)

View file

@ -300,11 +300,6 @@ void nano::active_transactions::request_confirm (nano::unique_lock<nano::mutex>
solicitor.flush ();
lock_a.lock ();
if (node.config.logging.timing_logging ())
{
node.logger.try_log (boost::str (boost::format ("Processed %1% elections (%2% were already confirmed) in %3% %4%") % this_loop_target_l % (this_loop_target_l - unconfirmed_count_l) % elapsed.value ().count () % elapsed.unit ()));
}
}
void nano::active_transactions::cleanup_election (nano::unique_lock<nano::mutex> & lock_a, std::shared_ptr<nano::election> election)
@ -313,7 +308,6 @@ void nano::active_transactions::cleanup_election (nano::unique_lock<nano::mutex>
debug_assert (lock_a.owns_lock ());
debug_assert (!election->confirmed () || recently_confirmed.exists (election->qualified_root));
node.stats.inc (completion_type (*election), nano::to_stat_detail (election->behavior ()));
// Keep track of election count by election type
debug_assert (count_by_behavior[election->behavior ()] > 0);
count_by_behavior[election->behavior ()]--;
@ -325,10 +319,15 @@ void nano::active_transactions::cleanup_election (nano::unique_lock<nano::mutex>
(void)erased;
debug_assert (erased == 1);
}
roots.get<tag_root> ().erase (roots.get<tag_root> ().find (election->qualified_root));
lock_a.unlock ();
node.stats.inc (completion_type (*election), nano::to_stat_detail (election->behavior ()));
vacancy_update ();
for (auto const & [hash, block] : blocks_l)
{
// Notify observers about dropped elections & blocks lost confirmed elections
@ -343,11 +342,6 @@ void nano::active_transactions::cleanup_election (nano::unique_lock<nano::mutex>
node.network.publish_filter.clear (block);
}
}
if (node.config.logging.election_result_logging ())
{
node.logger.try_log (boost::str (boost::format ("Election erased for root %1%, confirmed: %2$b") % election->qualified_root.to_string () % election->confirmed ()));
}
}
nano::stat::type nano::active_transactions::completion_type (nano::election const & election) const

View file

@ -112,19 +112,17 @@ void nano::block_processor::rollback_competitor (store::write_transaction const
if (successor != nullptr && successor->hash () != hash)
{
// Replace our block with the winner and roll back any dependent blocks
if (node.config.logging.ledger_rollback_logging ())
{
node.logger.always_log (boost::str (boost::format ("Rolling back %1% and replacing with %2%") % successor->hash ().to_string () % hash.to_string ()));
}
node.logger.debug (nano::log::type::blockprocessor, "Rolling back: {} and replacing with: {}", successor->hash ().to_string (), hash.to_string ());
std::vector<std::shared_ptr<nano::block>> rollback_list;
if (node.ledger.rollback (transaction, successor->hash (), rollback_list))
{
node.stats.inc (nano::stat::type::ledger, nano::stat::detail::rollback_failed);
node.logger.always_log (nano::severity_level::error, boost::str (boost::format ("Failed to roll back %1% because it or a successor was confirmed") % successor->hash ().to_string ()));
node.logger.error (nano::log::type::blockprocessor, "Failed to roll back: {} because it or a successor was confirmed", successor->hash ().to_string ());
}
else if (node.config.logging.ledger_rollback_logging ())
else
{
node.logger.always_log (boost::str (boost::format ("%1% blocks rolled back") % rollback_list.size ()));
node.logger.debug (nano::log::type::blockprocessor, "Blocks rolled back: {}", rollback_list.size ());
}
// Deleting from votes cache, stop active transaction
for (auto & i : rollback_list)
@ -176,7 +174,7 @@ bool nano::block_processor::should_log ()
auto now (std::chrono::steady_clock::now ());
if (next_log < now)
{
next_log = now + (node.config.logging.timing_logging () ? std::chrono::seconds (2) : std::chrono::seconds (15));
next_log = now + std::chrono::seconds (15);
result = true;
}
return result;
@ -218,10 +216,12 @@ auto nano::block_processor::process_batch (nano::unique_lock<nano::mutex> & lock
auto store_batch_reached = [&number_of_blocks_processed, max = node.store.max_block_write_batch_num ()] { return number_of_blocks_processed >= max; };
while (have_blocks_ready () && (!deadline_reached () || !processor_batch_reached ()) && !store_batch_reached ())
{
// TODO: Cleaner periodical logging
if ((blocks.size () + forced.size () > 64) && should_log ())
{
node.logger.always_log (boost::str (boost::format ("%1% blocks (+ %2% forced) in processing queue") % blocks.size () % forced.size ()));
node.logger.debug (nano::log::type::blockprocessor, "{} blocks (+ {} forced) in processing queue", blocks.size (), forced.size ());
}
std::shared_ptr<nano::block> block;
nano::block_hash hash (0);
bool force (false);
@ -251,10 +251,11 @@ auto nano::block_processor::process_batch (nano::unique_lock<nano::mutex> & lock
}
lock_a.unlock ();
if (node.config.logging.timing_logging () && number_of_blocks_processed != 0 && timer_l.stop () > std::chrono::milliseconds (100))
if (number_of_blocks_processed != 0 && timer_l.stop () > std::chrono::milliseconds (100))
{
node.logger.always_log (boost::str (boost::format ("Processed %1% blocks (%2% blocks were forced) in %3% %4%") % number_of_blocks_processed % number_of_forced_processed % timer_l.value ().count () % timer_l.unit ()));
node.logger.debug (nano::log::type::blockprocessor, "Processed {} blocks ({} forced) in {} {}", number_of_blocks_processed, number_of_forced_processed, timer_l.value ().count (), timer_l.unit ());
}
return processed;
}
@ -263,16 +264,13 @@ nano::process_return nano::block_processor::process_one (store::write_transactio
nano::process_return result;
auto hash (block->hash ());
result = node.ledger.process (transaction_a, *block);
node.stats.inc (nano::stat::type::blockprocessor, to_stat_detail (result.code));
switch (result.code)
{
case nano::process_result::progress:
{
if (node.config.logging.ledger_logging ())
{
std::string block_string;
block->serialize_json (block_string, node.config.logging.single_line_record ());
node.logger.try_log (boost::str (boost::format ("Processing block %1%: %2%") % hash.to_string () % block_string));
}
queue_unchecked (transaction_a, hash);
/* For send blocks check epoch open unchecked (gap pending).
For state blocks check only send subtype and only if block epoch is not last epoch.
@ -287,120 +285,65 @@ nano::process_return nano::block_processor::process_one (store::write_transactio
}
case nano::process_result::gap_previous:
{
if (node.config.logging.ledger_logging ())
{
node.logger.try_log (boost::str (boost::format ("Gap previous for: %1%") % hash.to_string ()));
}
node.unchecked.put (block->previous (), block);
node.stats.inc (nano::stat::type::ledger, nano::stat::detail::gap_previous);
break;
}
case nano::process_result::gap_source:
{
if (node.config.logging.ledger_logging ())
{
node.logger.try_log (boost::str (boost::format ("Gap source for: %1%") % hash.to_string ()));
}
node.unchecked.put (node.ledger.block_source (transaction_a, *block), block);
node.stats.inc (nano::stat::type::ledger, nano::stat::detail::gap_source);
break;
}
case nano::process_result::gap_epoch_open_pending:
{
if (node.config.logging.ledger_logging ())
{
node.logger.try_log (boost::str (boost::format ("Gap pending entries for epoch open: %1%") % hash.to_string ()));
}
node.unchecked.put (block->account (), block); // Specific unchecked key starting with epoch open block account public key
node.stats.inc (nano::stat::type::ledger, nano::stat::detail::gap_source);
break;
}
case nano::process_result::old:
{
if (node.config.logging.ledger_duplicate_logging ())
{
node.logger.try_log (boost::str (boost::format ("Old for: %1%") % hash.to_string ()));
}
node.stats.inc (nano::stat::type::ledger, nano::stat::detail::old);
break;
}
case nano::process_result::bad_signature:
{
if (node.config.logging.ledger_logging ())
{
node.logger.try_log (boost::str (boost::format ("Bad signature for: %1%") % hash.to_string ()));
}
break;
}
case nano::process_result::negative_spend:
{
if (node.config.logging.ledger_logging ())
{
node.logger.try_log (boost::str (boost::format ("Negative spend for: %1%") % hash.to_string ()));
}
break;
}
case nano::process_result::unreceivable:
{
if (node.config.logging.ledger_logging ())
{
node.logger.try_log (boost::str (boost::format ("Unreceivable for: %1%") % hash.to_string ()));
}
break;
}
case nano::process_result::fork:
{
node.stats.inc (nano::stat::type::ledger, nano::stat::detail::fork);
if (node.config.logging.ledger_logging ())
{
node.logger.try_log (boost::str (boost::format ("Fork for: %1% root: %2%") % hash.to_string () % block->root ().to_string ()));
}
break;
}
case nano::process_result::opened_burn_account:
{
if (node.config.logging.ledger_logging ())
{
node.logger.try_log (boost::str (boost::format ("Rejecting open block for burn account: %1%") % hash.to_string ()));
}
break;
}
case nano::process_result::balance_mismatch:
{
if (node.config.logging.ledger_logging ())
{
node.logger.try_log (boost::str (boost::format ("Balance mismatch for: %1%") % hash.to_string ()));
}
break;
}
case nano::process_result::representative_mismatch:
{
if (node.config.logging.ledger_logging ())
{
node.logger.try_log (boost::str (boost::format ("Representative mismatch for: %1%") % hash.to_string ()));
}
break;
}
case nano::process_result::block_position:
{
if (node.config.logging.ledger_logging ())
{
node.logger.try_log (boost::str (boost::format ("Block %1% cannot follow predecessor %2%") % hash.to_string () % block->previous ().to_string ()));
}
break;
}
case nano::process_result::insufficient_work:
{
if (node.config.logging.ledger_logging ())
{
node.logger.try_log (boost::str (boost::format ("Insufficient work for %1% : %2% (difficulty %3%)") % hash.to_string () % nano::to_string_hex (block->block_work ()) % nano::to_string_hex (node.network_params.work.difficulty (*block))));
}
break;
}
}
node.stats.inc (nano::stat::type::blockprocessor, nano::to_stat_detail (result.code));
return result;
}

View file

@ -1,6 +1,7 @@
#pragma once
#include <nano/lib/blocks.hpp>
#include <nano/lib/logging.hpp>
#include <nano/node/blocking_observer.hpp>
#include <nano/secure/common.hpp>

View file

@ -20,7 +20,8 @@ nano::bootstrap_attempt::bootstrap_attempt (std::shared_ptr<nano::node> const &
id = nano::hardened_constants::get ().random_128.to_string ();
}
node_a->logger.always_log (boost::str (boost::format ("Starting %1% bootstrap attempt with ID %2%") % mode_text () % id));
node_a->logger.debug (nano::log::type::bootstrap, "Starting bootstrap attempt with ID: {} (mode: {})", mode_text (), id);
node_a->bootstrap_initiator.notify_listeners (true);
if (node_a->websocket.server)
{
@ -36,7 +37,9 @@ nano::bootstrap_attempt::~bootstrap_attempt ()
{
return;
}
node->logger.always_log (boost::str (boost::format ("Exiting %1% bootstrap attempt with ID %2%") % mode_text () % id));
node->logger.debug (nano::log::type::bootstrap, "Exiting bootstrap attempt with ID: {} (mode: {})", mode_text (), id);
node->bootstrap_initiator.notify_listeners (false);
if (node->websocket.server)
{

View file

@ -46,10 +46,8 @@ nano::bulk_pull_client::~bulk_pull_client ()
}
pull.processed += pull_blocks - unexpected_count;
node->bootstrap_initiator.connections->requeue_pull (pull, network_error);
if (node->config.logging.bulk_pull_logging ())
{
node->logger.try_log (boost::str (boost::format ("Bulk pull end block is not expected %1% for account %2% or head block %3%") % pull.end.to_string () % pull.account_or_head.to_account () % pull.account_or_head.to_string ()));
}
node->logger.debug (nano::log::type::bulk_pull_client, "Bulk pull end block is not expected {} for account {} or head block {}", pull.end.to_string (), pull.account_or_head.to_account (), pull.account_or_head.to_string ());
}
else
{
@ -82,14 +80,11 @@ void nano::bulk_pull_client::request ()
req.count = pull.count;
req.set_count_present (pull.count != 0);
if (node->config.logging.bulk_pull_logging ())
if (attempt->should_log ())
{
node->logger.try_log (boost::str (boost::format ("Requesting account %1% or head block %2% from %3%. %4% accounts in queue") % pull.account_or_head.to_account () % pull.account_or_head.to_string () % connection->channel->to_string () % attempt->pulling));
}
else if (node->config.logging.network_logging () && attempt->should_log ())
{
node->logger.always_log (boost::str (boost::format ("%1% accounts in pull queue") % attempt->pulling));
node->logger.debug (nano::log::type::bulk_pull_client, "Accounts in pull queue: {}", attempt->pulling.load ());
}
auto this_l (shared_from_this ());
connection->channel->send (
req, [this_l] (boost::system::error_code const & ec, std::size_t size_a) {
@ -104,10 +99,7 @@ void nano::bulk_pull_client::request ()
}
else
{
if (node->config.logging.bulk_pull_logging ())
{
node->logger.try_log (boost::str (boost::format ("Error sending bulk pull request to %1%: to %2%") % ec.message () % this_l->connection->channel->to_string ()));
}
node->logger.debug (nano::log::type::bulk_pull_client, "Error sending bulk pull request to: {} ({})", this_l->connection->channel->to_string (), ec.message ());
node->stats.inc (nano::stat::type::bootstrap, nano::stat::detail::bulk_pull_request_failure, nano::stat::dir::in);
}
},
@ -168,20 +160,12 @@ void nano::bulk_pull_client::received_block (boost::system::error_code ec, std::
}
if (node->network_params.work.validate_entry (*block))
{
if (node->config.logging.bulk_pull_logging ())
{
node->logger.try_log (boost::str (boost::format ("Insufficient work for bulk pull block: %1%") % block->hash ().to_string ()));
}
node->stats.inc_detail_only (nano::stat::type::error, nano::stat::detail::insufficient_work);
node->logger.debug (nano::log::type::bulk_pull_client, "Insufficient work for bulk pull block: {}", block->hash ().to_string ());
node->stats.inc (nano::stat::type::error, nano::stat::detail::insufficient_work);
return;
}
auto hash = block->hash ();
if (node->config.logging.bulk_pull_logging ())
{
std::string block_l;
block->serialize_json (block_l, node->config.logging.single_line_record ());
node->logger.try_log (boost::str (boost::format ("Pulled block %1% %2%") % hash.to_string () % block_l));
}
// Is block expected?
bool block_expected (false);
// Unconfirmed head is used only for lazy destinations if legacy bootstrap is not available, see nano::bootstrap_attempt::lazy_destinations_increment (...)
@ -247,14 +231,12 @@ void nano::bulk_pull_account_client::request ()
req.account = account;
req.minimum_amount = node->config.receive_minimum;
req.flags = nano::bulk_pull_account_flags::pending_hash_and_amount;
if (node->config.logging.bulk_pull_logging ())
if (attempt->should_log ())
{
node->logger.try_log (boost::str (boost::format ("Requesting pending for account %1% from %2%. %3% accounts in queue") % req.account.to_account () % connection->channel->to_string () % attempt->wallet_size ()));
}
else if (node->config.logging.network_logging () && attempt->should_log ())
{
node->logger.always_log (boost::str (boost::format ("%1% accounts in pull queue") % attempt->wallet_size ()));
node->logger.debug (nano::log::type::bulk_pull_account_client, "Accounts in pull queue: {}", attempt->wallet_size ());
}
auto this_l (shared_from_this ());
connection->channel->send (
req, [this_l] (boost::system::error_code const & ec, std::size_t size_a) {
@ -269,12 +251,10 @@ void nano::bulk_pull_account_client::request ()
}
else
{
this_l->attempt->requeue_pending (this_l->account);
if (node->config.logging.bulk_pull_logging ())
{
node->logger.try_log (boost::str (boost::format ("Error starting bulk pull request to %1%: to %2%") % ec.message () % this_l->connection->channel->to_string ()));
}
node->logger.debug (nano::log::type::bulk_pull_account_client, "Error starting bulk pull request to: {} ({})", this_l->connection->channel->to_string (), ec.message ());
node->stats.inc (nano::stat::type::bootstrap, nano::stat::detail::bulk_pull_error_starting_request, nano::stat::dir::in);
this_l->attempt->requeue_pending (this_l->account);
}
},
nano::transport::buffer_drop_policy::no_limiter_drop);
@ -334,20 +314,16 @@ void nano::bulk_pull_account_client::receive_pending ()
}
else
{
node->logger.debug (nano::log::type::bulk_pull_account_client, "Error while receiving bulk pull account frontier: {}", ec.message ());
this_l->attempt->requeue_pending (this_l->account);
if (node->config.logging.network_logging ())
{
node->logger.try_log (boost::str (boost::format ("Error while receiving bulk pull account frontier %1%") % ec.message ()));
}
}
}
else
{
node->logger.debug (nano::log::type::bulk_pull_account_client, "Invalid size: Expected {}, got: {}", size_l, size_a);
this_l->attempt->requeue_pending (this_l->account);
if (node->config.logging.network_message_logging ())
{
node->logger.try_log (boost::str (boost::format ("Invalid size: expected %1%, got %2%") % size_l % size_a));
}
}
});
}
@ -379,19 +355,14 @@ void nano::bulk_pull_server::set_current_end ()
auto transaction (node->store.tx_begin_read ());
if (!node->store.block.exists (transaction, request->end))
{
if (node->config.logging.bulk_pull_logging ())
{
node->logger.try_log (boost::str (boost::format ("Bulk pull end block doesn't exist: %1%, sending everything") % request->end.to_string ()));
}
node->logger.debug (nano::log::type::bulk_pull_server, "Bulk pull end block doesn't exist: {}, sending everything", request->end.to_string ());
request->end.clear ();
}
if (node->store.block.exists (transaction, request->start.as_block_hash ()))
{
if (node->config.logging.bulk_pull_logging ())
{
node->logger.try_log (boost::str (boost::format ("Bulk pull request for block hash: %1%") % request->start.to_string ()));
}
node->logger.debug (nano::log::type::bulk_pull_server, "Bulk pull request for block hash: {}", request->start.to_string ());
current = ascending () ? node->store.block.successor (transaction, request->start.as_block_hash ()) : request->start.as_block_hash ();
include_start = true;
@ -401,10 +372,8 @@ void nano::bulk_pull_server::set_current_end ()
auto info = node->ledger.account_info (transaction, request->start.as_account ());
if (!info)
{
if (node->config.logging.bulk_pull_logging ())
{
node->logger.try_log (boost::str (boost::format ("Request for unknown account: %1%") % request->start.to_account ()));
}
node->logger.debug (nano::log::type::bulk_pull_server, "Request for unknown account: {}", request->start.to_account ());
current = request->end;
}
else
@ -415,10 +384,8 @@ void nano::bulk_pull_server::set_current_end ()
auto account (node->ledger.account (transaction, request->end));
if (account != request->start.as_account ())
{
if (node->config.logging.bulk_pull_logging ())
{
node->logger.try_log (boost::str (boost::format ("Request for block that is not on account chain: %1% not on %2%") % request->end.to_string () % request->start.to_account ()));
}
node->logger.debug (nano::log::type::bulk_pull_server, "Request for block that is not on account chain: {} not on {}", request->end.to_string (), request->start.to_account ());
current = request->end;
}
}
@ -451,10 +418,7 @@ void nano::bulk_pull_server::send_next ()
nano::vectorstream stream (send_buffer);
nano::serialize_block (stream, *block);
}
if (node->config.logging.bulk_pull_logging ())
{
node->logger.try_log (boost::str (boost::format ("Sending block: %1%") % block->hash ().to_string ()));
}
connection->socket->async_write (nano::shared_const_buffer (std::move (send_buffer)), [this_l = shared_from_this ()] (boost::system::error_code const & ec, std::size_t size_a) {
this_l->sent_action (ec, size_a);
});
@ -556,10 +520,7 @@ void nano::bulk_pull_server::sent_action (boost::system::error_code const & ec,
}
else
{
if (node->config.logging.bulk_pull_logging ())
{
node->logger.try_log (boost::str (boost::format ("Unable to bulk send block: %1%") % ec.message ()));
}
node->logger.debug (nano::log::type::bulk_pull_server, "Unable to bulk send block: {}", ec.message ());
}
}
@ -572,10 +533,9 @@ void nano::bulk_pull_server::send_finished ()
}
nano::shared_const_buffer send_buffer (static_cast<uint8_t> (nano::block_type::not_a_block));
auto this_l (shared_from_this ());
if (node->config.logging.bulk_pull_logging ())
{
node->logger.try_log ("Bulk sending finished");
}
node->logger.debug (nano::log::type::bulk_pull_server, "Bulk sending finished");
connection->socket->async_write (send_buffer, [this_l] (boost::system::error_code const & ec, std::size_t size_a) {
this_l->no_block_sent (ec, size_a);
});
@ -595,10 +555,7 @@ void nano::bulk_pull_server::no_block_sent (boost::system::error_code const & ec
}
else
{
if (node->config.logging.bulk_pull_logging ())
{
node->logger.try_log ("Unable to send not-a-block");
}
node->logger.debug (nano::log::type::bulk_pull_server, "Unable to bulk send not-a-block: {}", ec.message ());
}
}
@ -650,13 +607,9 @@ void nano::bulk_pull_account_server::set_params ()
}
else
{
if (node->config.logging.bulk_pull_logging ())
{
node->logger.try_log (boost::str (boost::format ("Invalid bulk_pull_account flags supplied %1%") % static_cast<uint8_t> (request->flags)));
}
node->logger.debug (nano::log::type::bulk_pull_account_server, "Invalid bulk_pull_account flags supplied: {}", static_cast<uint8_t> (request->flags));
invalid_request = true;
return;
}
@ -729,23 +682,11 @@ void nano::bulk_pull_account_server::send_next_block ()
if (pending_address_only)
{
nano::vectorstream output_stream (send_buffer);
if (node->config.logging.bulk_pull_logging ())
{
node->logger.try_log (boost::str (boost::format ("Sending address: %1%") % block_info->source.to_string ()));
}
write (output_stream, block_info->source.bytes);
}
else
{
nano::vectorstream output_stream (send_buffer);
if (node->config.logging.bulk_pull_logging ())
{
node->logger.try_log (boost::str (boost::format ("Sending block: %1%") % block_info_key->hash.to_string ()));
}
write (output_stream, block_info_key->hash.bytes);
write (output_stream, block_info->amount.bytes);
@ -768,10 +709,7 @@ void nano::bulk_pull_account_server::send_next_block ()
/*
* Otherwise, finalize the connection
*/
if (node->config.logging.bulk_pull_logging ())
{
node->logger.try_log (boost::str (boost::format ("Done sending blocks")));
}
node->logger.debug (nano::log::type::bulk_pull_account_server, "Done sending blocks");
send_finished ();
}
@ -876,10 +814,7 @@ void nano::bulk_pull_account_server::sent_action (boost::system::error_code cons
}
else
{
if (node->config.logging.bulk_pull_logging ())
{
node->logger.try_log (boost::str (boost::format ("Unable to bulk send block: %1%") % ec.message ()));
}
node->logger.debug (nano::log::type::bulk_pull_account_server, "Unable to bulk send block: {}", ec.message ());
}
}
@ -916,13 +851,9 @@ void nano::bulk_pull_account_server::send_finished ()
}
}
node->logger.debug (nano::log::type::bulk_pull_account_server, "Bulk sending for an account finished");
auto this_l (shared_from_this ());
if (node->config.logging.bulk_pull_logging ())
{
node->logger.try_log ("Bulk sending for an account finished");
}
connection->socket->async_write (nano::shared_const_buffer (std::move (send_buffer)), [this_l] (boost::system::error_code const & ec, std::size_t size_a) {
this_l->complete (ec, size_a);
});
@ -957,10 +888,7 @@ void nano::bulk_pull_account_server::complete (boost::system::error_code const &
}
else
{
if (node->config.logging.bulk_pull_logging ())
{
node->logger.try_log ("Unable to pending-as-zero");
}
node->logger.debug (nano::log::type::bulk_pull_account_server, "Unable to pending-as-zero: {}", ec.message ());
}
}

View file

@ -38,10 +38,7 @@ void nano::bulk_push_client::start ()
}
else
{
if (node->config.logging.bulk_pull_logging ())
{
node->logger.try_log (boost::str (boost::format ("Unable to send bulk_push request: %1%") % ec.message ()));
}
node->logger.debug (nano::log::type::bulk_push_client, "Unable to send bulk push request: {}", ec.message ());
}
},
nano::transport::buffer_drop_policy::no_limiter_drop);
@ -71,10 +68,7 @@ void nano::bulk_push_client::push ()
}
else
{
if (node->config.logging.bulk_pull_logging ())
{
node->logger.try_log ("Bulk pushing range ", current_target.first.to_string (), " down to ", current_target.second.to_string ());
}
node->logger.debug (nano::log::type::bulk_push_client, "Bulk pushing range: [{}:{}]", current_target.first.to_string (), current_target.second.to_string ());
}
}
}
@ -124,10 +118,7 @@ void nano::bulk_push_client::push_block (nano::block const & block_a)
}
else
{
if (node->config.logging.bulk_pull_logging ())
{
node->logger.try_log (boost::str (boost::format ("Error sending block during bulk push: %1%") % ec.message ()));
}
node->logger.debug (nano::log::type::bulk_push_client, "Error sending block during bulk push: {}", ec.message ());
}
});
}
@ -171,10 +162,7 @@ void nano::bulk_push_server::receive ()
}
if (node->bootstrap_initiator.in_progress ())
{
if (node->config.logging.bulk_pull_logging ())
{
node->logger.try_log ("Aborting bulk_push because a bootstrap attempt is in progress");
}
node->logger.debug (nano::log::type::bulk_push_server, "Aborting bulk push because a bootstrap attempt is in progress");
}
else
{
@ -191,10 +179,7 @@ void nano::bulk_push_server::receive ()
}
else
{
if (node->config.logging.bulk_pull_logging ())
{
node->logger.try_log (boost::str (boost::format ("Error receiving block type: %1%") % ec.message ()));
}
node->logger.debug (nano::log::type::bulk_push_server, "Error receiving block type: {}", ec.message ());
}
});
}
@ -258,10 +243,7 @@ void nano::bulk_push_server::received_type ()
}
default:
{
if (node->config.logging.network_packet_logging ())
{
node->logger.try_log ("Unknown type received as block type");
}
node->logger.debug (nano::log::type::bulk_push_server, "Unknown type received as block type");
break;
}
}
@ -282,11 +264,8 @@ void nano::bulk_push_server::received_block (boost::system::error_code const & e
{
if (node->network_params.work.validate_entry (*block))
{
if (node->config.logging.bulk_pull_logging ())
{
node->logger.try_log (boost::str (boost::format ("Insufficient work for bulk push block: %1%") % block->hash ().to_string ()));
}
node->stats.inc_detail_only (nano::stat::type::error, nano::stat::detail::insufficient_work);
node->logger.debug (nano::log::type::bulk_push_server, "Insufficient work for bulk push block: {}", block->hash ().to_string ());
node->stats.inc (nano::stat::type::error, nano::stat::detail::insufficient_work);
return;
}
node->process_active (std::move (block));
@ -294,10 +273,7 @@ void nano::bulk_push_server::received_block (boost::system::error_code const & e
}
else
{
if (node->config.logging.bulk_pull_logging ())
{
node->logger.try_log ("Error deserializing block received from pull request");
}
node->logger.debug (nano::log::type::bulk_push_server, "Error deserializing block received from pull request");
}
}
}

View file

@ -91,7 +91,8 @@ std::shared_ptr<nano::bootstrap_client> nano::bootstrap_connections::connection
}
if (result == nullptr && connections_count == 0 && new_connections_empty && attempt_a != nullptr)
{
node.logger.try_log (boost::str (boost::format ("Bootstrap attempt stopped because there are no peers")));
node.logger.debug (nano::log::type::bootstrap, "Bootstrap attempt stopped because there are no peers");
lock.unlock ();
attempt_a->stop ();
}
@ -157,29 +158,24 @@ void nano::bootstrap_connections::connect_client (nano::tcp_endpoint const & end
[this_l, socket, endpoint_a, push_front] (boost::system::error_code const & ec) {
if (!ec)
{
if (this_l->node.config.logging.bulk_pull_logging ())
{
this_l->node.logger.try_log (boost::str (boost::format ("Connection established to %1%") % endpoint_a));
}
this_l->node.logger.debug (nano::log::type::bootstrap, "Connection established to: {}", nano::util::to_str (endpoint_a));
auto client (std::make_shared<nano::bootstrap_client> (this_l->node.shared (), std::make_shared<nano::transport::channel_tcp> (*this_l->node.shared (), socket), socket));
this_l->pool_connection (client, true, push_front);
}
else
{
if (this_l->node.config.logging.network_logging ())
switch (ec.value ())
{
switch (ec.value ())
{
default:
this_l->node.logger.try_log (boost::str (boost::format ("Error initiating bootstrap connection to %1%: %2%") % endpoint_a % ec.message ()));
break;
case boost::system::errc::connection_refused:
case boost::system::errc::operation_canceled:
case boost::system::errc::timed_out:
case 995: // Windows The I/O operation has been aborted because of either a thread exit or an application request
case 10061: // Windows No connection could be made because the target machine actively refused it
break;
}
default:
this_l->node.logger.debug (nano::log::type::bootstrap, "Error initiating bootstrap connection to: {} ({})", nano::util::to_str (endpoint_a), ec.message ());
break;
case boost::system::errc::connection_refused:
case boost::system::errc::operation_canceled:
case boost::system::errc::timed_out:
case 995: // Windows The I/O operation has been aborted because of either a thread exit or an application request
case 10061: // Windows No connection could be made because the target machine actively refused it
break;
}
}
--this_l->connections_count;
@ -236,10 +232,12 @@ void nano::bootstrap_connections::populate_connections (bool repeat)
// This is ~1.5kilobits/sec.
if (elapsed_sec > nano::bootstrap_limits::bootstrap_minimum_termination_time_sec && blocks_per_sec < nano::bootstrap_limits::bootstrap_minimum_blocks_per_sec)
{
if (node.config.logging.bulk_pull_logging ())
{
node.logger.try_log (boost::str (boost::format ("Stopping slow peer %1% (elapsed sec %2%s > %3%s and %4% blocks per second < %5%)") % client->channel->to_string () % elapsed_sec % nano::bootstrap_limits::bootstrap_minimum_termination_time_sec % blocks_per_sec % nano::bootstrap_limits::bootstrap_minimum_blocks_per_sec));
}
node.logger.debug (nano::log::type::bootstrap, "Stopping slow peer {} (elapsed sec {} > {} and {} blocks per second < {})",
client->channel->to_string (),
elapsed_sec,
nano::bootstrap_limits::bootstrap_minimum_termination_time_sec,
blocks_per_sec,
nano::bootstrap_limits::bootstrap_minimum_blocks_per_sec);
client->stop (true);
new_clients.pop_back ();
@ -259,29 +257,27 @@ void nano::bootstrap_connections::populate_connections (bool repeat)
// 4 -> 1, 8 -> 2, 16 -> 4, arbitrary, but seems to work well.
auto drop = (int)roundf (sqrtf ((float)target - 2.0f));
if (node.config.logging.bulk_pull_logging ())
{
node.logger.try_log (boost::str (boost::format ("Dropping %1% bulk pull peers, target connections %2%") % drop % target));
}
node.logger.debug (nano::log::type::bootstrap, "Dropping {} bulk pull peers, target connections {}", drop, target);
for (int i = 0; i < drop; i++)
{
auto client = sorted_connections.top ();
if (node.config.logging.bulk_pull_logging ())
{
node.logger.try_log (boost::str (boost::format ("Dropping peer with block rate %1%, block count %2% (%3%) ") % client->block_rate % client->block_count % client->channel->to_string ()));
}
node.logger.debug (nano::log::type::bootstrap, "Dropping peer with block rate {} and block count {} ({})",
client->block_rate.load (),
client->block_count.load (),
client->channel->to_string ());
client->stop (false);
sorted_connections.pop ();
}
}
if (node.config.logging.bulk_pull_logging ())
{
node.logger.try_log (boost::str (boost::format ("Bulk pull connections: %1%, rate: %2% blocks/sec, bootstrap attempts %3%, remaining pulls: %4%") % connections_count.load () % (int)rate_sum % attempts_count % num_pulls));
}
node.logger.debug (nano::log::type::bootstrap, "Bulk pull connections: {}, rate: {} blocks/sec, bootstrap attempts {}, remaining pulls: {}",
connections_count.load (),
(int)rate_sum,
attempts_count,
num_pulls);
if (connections_count < target && (attempts_count != 0 || new_connections_empty) && !stopped)
{
@ -423,11 +419,13 @@ void nano::bootstrap_connections::requeue_pull (nano::pull_info const & pull_a,
}
else
{
if (node.config.logging.bulk_pull_logging ())
{
node.logger.try_log (boost::str (boost::format ("Failed to pull account %1% or head block %2% down to %3% after %4% attempts and %5% blocks processed") % pull.account_or_head.to_account () % pull.account_or_head.to_string () % pull.end.to_string () % pull.attempts % pull.processed));
}
node.stats.inc (nano::stat::type::bootstrap, nano::stat::detail::bulk_pull_failed_account, nano::stat::dir::in);
node.logger.debug (nano::log::type::bootstrap, "Failed to pull account {} or head block {} down to {} after {} attempts and {} blocks processed",
pull.account_or_head.to_account (),
pull.account_or_head.to_string (),
pull.end.to_string (),
pull.attempts,
pull.processed);
if (lazy && pull.processed > 0)
{

View file

@ -42,10 +42,7 @@ void nano::frontier_req_client::run (nano::account const & start_account_a, uint
}
else
{
if (node->config.logging.network_logging ())
{
node->logger.try_log (boost::str (boost::format ("Error while sending bootstrap request %1%") % ec.message ()));
}
node->logger.debug (nano::log::type::frontier_req_client, "Error while sending bootstrap request: {}", ec.message ());
}
},
nano::transport::buffer_drop_policy::no_limiter_drop);
@ -76,10 +73,7 @@ void nano::frontier_req_client::receive_frontier ()
}
else
{
if (node->config.logging.network_message_logging ())
{
node->logger.try_log (boost::str (boost::format ("Invalid size: expected %1%, got %2%") % nano::frontier_req_client::size_frontier % size_a));
}
node->logger.debug (nano::log::type::frontier_req_client, "Invalid size: expected {}, got {}", nano::frontier_req_client::size_frontier, size_a);
}
});
}
@ -137,14 +131,17 @@ void nano::frontier_req_client::received_frontier (boost::system::error_code con
double age_factor = (frontiers_age == std::numeric_limits<decltype (frontiers_age)>::max ()) ? 1.0 : 1.5; // Allow slower frontiers receive for requests with age
if (elapsed_sec > nano::bootstrap_limits::bootstrap_connection_warmup_time_sec && blocks_per_sec * age_factor < nano::bootstrap_limits::bootstrap_minimum_frontier_blocks_per_sec)
{
node->logger.try_log (boost::str (boost::format ("Aborting frontier req because it was too slow: %1% frontiers per second, last %2%") % blocks_per_sec % account.to_account ()));
node->logger.debug (nano::log::type::frontier_req_client, "Aborting frontier req because it was too slow: {} frontiers per second, last {}", blocks_per_sec, account.to_account ());
promise.set_value (true);
return;
}
if (attempt->should_log ())
{
node->logger.always_log (boost::str (boost::format ("Received %1% frontiers from %2%") % std::to_string (count) % connection->channel->to_string ()));
node->logger.debug (nano::log::type::frontier_req_client, "Received {} frontiers from {}", count, connection->channel->to_string ());
}
if (!account.is_zero () && count <= count_limit)
{
last_account = account;
@ -203,10 +200,8 @@ void nano::frontier_req_client::received_frontier (boost::system::error_code con
}
// Prevent new frontier_req requests
attempt->set_start_account (std::numeric_limits<nano::uint256_t>::max ());
if (node->config.logging.bulk_pull_logging ())
{
node->logger.try_log ("Bulk push cost: ", bulk_push_cost);
}
node->logger.debug (nano::log::type::frontier_req_client, "Bulk push cost: {}", bulk_push_cost);
}
else
{
@ -225,10 +220,7 @@ void nano::frontier_req_client::received_frontier (boost::system::error_code con
}
else
{
if (node->config.logging.network_logging ())
{
node->logger.try_log (boost::str (boost::format ("Error while receiving frontier %1%") % ec.message ()));
}
node->logger.debug (nano::log::type::frontier_req_client, "Error while receiving frontier: {}", ec.message ());
}
}
@ -291,11 +283,8 @@ void nano::frontier_req_server::send_next ()
debug_assert (!current.is_zero ());
debug_assert (!frontier.is_zero ());
}
auto this_l (shared_from_this ());
if (node->config.logging.bulk_pull_logging ())
{
node->logger.try_log (boost::str (boost::format ("Sending frontier for %1% %2%") % current.to_account () % frontier.to_string ()));
}
next ();
connection->socket->async_write (nano::shared_const_buffer (std::move (send_buffer)), [this_l] (boost::system::error_code const & ec, std::size_t size_a) {
this_l->sent_action (ec, size_a);
@ -321,11 +310,10 @@ void nano::frontier_req_server::send_finished ()
write (stream, zero.bytes);
write (stream, zero.bytes);
}
node->logger.debug (nano::log::type::frontier_req_server, "Frontier sending finished");
auto this_l (shared_from_this ());
if (node->config.logging.network_logging ())
{
node->logger.try_log ("Frontier sending finished");
}
connection->socket->async_write (nano::shared_const_buffer (std::move (send_buffer)), [this_l] (boost::system::error_code const & ec, std::size_t size_a) {
this_l->no_block_sent (ec, size_a);
});
@ -344,10 +332,7 @@ void nano::frontier_req_server::no_block_sent (boost::system::error_code const &
}
else
{
if (node->config.logging.network_logging ())
{
node->logger.try_log (boost::str (boost::format ("Error sending frontier finish: %1%") % ec.message ()));
}
node->logger.debug (nano::log::type::frontier_req_server, "Error sending frontier finish: {}", ec.message ());
}
}
@ -368,10 +353,7 @@ void nano::frontier_req_server::sent_action (boost::system::error_code const & e
}
else
{
if (node->config.logging.network_logging ())
{
node->logger.try_log (boost::str (boost::format ("Error sending frontier pair: %1%") % ec.message ()));
}
node->logger.debug (nano::log::type::frontier_req_server, "Error sending frontier pair: {}", ec.message ());
}
}

View file

@ -250,11 +250,11 @@ void nano::bootstrap_attempt_lazy::run ()
}
if (!stopped)
{
node->logger.try_log ("Completed lazy pulls");
node->logger.debug (nano::log::type::bootstrap_lazy, "Completed lazy pulls");
}
if (lazy_has_expired ())
{
node->logger.try_log (boost::str (boost::format ("Lazy bootstrap attempt ID %1% expired") % id));
node->logger.debug (nano::log::type::bootstrap_lazy, "Lazy bootstrap attempt ID {} expired", id);
}
lock.unlock ();
stop ();
@ -613,7 +613,7 @@ void nano::bootstrap_attempt_wallet::run ()
}
if (!stopped)
{
node->logger.try_log ("Completed wallet lazy pulls");
node->logger.info (nano::log::type::bootstrap_lazy, "Completed wallet lazy pulls");
}
lock.unlock ();
stop ();

View file

@ -88,14 +88,6 @@ void nano::bootstrap_attempt_legacy::request_push (nano::unique_lock<nano::mutex
error = consume_future (future); // This is out of scope of `client' so when the last reference via boost::asio::io_context is lost and the client is destroyed, the future throws an exception.
lock_a.lock ();
}
if (node->config.logging.network_logging ())
{
node->logger.try_log ("Exiting bulk push client");
if (error)
{
node->logger.try_log ("Bulk push client failed");
}
}
}
void nano::bootstrap_attempt_legacy::add_frontier (nano::pull_info const & pull_a)
@ -186,16 +178,13 @@ bool nano::bootstrap_attempt_legacy::request_frontier (nano::unique_lock<nano::m
frontier_pulls.pop_front ();
}
}
if (node->config.logging.network_logging ())
if (!result)
{
if (!result)
{
node->logger.try_log (boost::str (boost::format ("Completed frontier request, %1% out of sync accounts according to %2%") % account_count % connection_l->channel->to_string ()));
}
else
{
node->stats.inc (nano::stat::type::error, nano::stat::detail::frontier_req, nano::stat::dir::out);
}
node->logger.debug (nano::log::type::bootstrap_legacy, "Completed frontier request, {} out of sync accounts according to {}", account_count.load (), connection_l->channel->to_string ());
}
else
{
node->stats.inc (nano::stat::type::error, nano::stat::detail::frontier_req, nano::stat::dir::out);
}
}
return result;
@ -233,25 +222,24 @@ void nano::bootstrap_attempt_legacy::run ()
// clang-format off
condition.wait (lock, [&stopped = stopped, &pulling = pulling] { return stopped || pulling == 0; });
}
// Flushing may resolve forks which can add more pulls
node->logger.try_log ("Flushing unchecked blocks");
lock.unlock ();
node->block_processor.flush ();
lock.lock ();
if (start_account.number () != std::numeric_limits<nano::uint256_t>::max ())
{
node->logger.try_log (boost::str (boost::format ("Finished flushing unchecked blocks, requesting new frontiers after %1%") % start_account.to_account ()));
node->logger.debug(nano::log::type::bootstrap_legacy, "Requesting new frontiers after: {}", start_account.to_account ());
// Requesting new frontiers
run_start (lock);
}
else
{
node->logger.try_log ("Finished flushing unchecked blocks");
}
}
if (!stopped)
{
node->logger.try_log ("Completed legacy pulls");
node->logger.debug(nano::log::type::bootstrap_legacy, "Completed legacy pulls");
if (!node->flags.disable_bootstrap_bulk_push_client)
{
request_push (lock);

View file

@ -58,7 +58,7 @@ void nano::add_node_options (boost::program_options::options_description & descr
("rebuild_database", "Rebuild LMDB database with vacuum for best compaction")
("migrate_database_lmdb_to_rocksdb", "Migrates LMDB database to RocksDB")
("diagnostics", "Run internal diagnostics")
("generate_config", boost::program_options::value<std::string> (), "Write configuration to stdout, populated with defaults suitable for this system. Pass the configuration type node, rpc or tls. See also use_defaults.")
("generate_config", boost::program_options::value<std::string> (), "Write configuration to stdout, populated with defaults suitable for this system. Pass the configuration type node, rpc or log. See also use_defaults.")
("key_create", "Generates a adhoc random keypair and prints it to stdout")
("key_expand", "Derive public key and account number from <key>")
("wallet_add_adhoc", "Insert <key> in to <wallet>")
@ -254,6 +254,9 @@ std::error_code nano::handle_node_options (boost::program_options::variables_map
if (vm.count ("initialize"))
{
// TODO: --config flag overrides are not taken into account here
nano::logger::initialize (nano::log_config::daemon_default (), data_path);
auto node_flags = nano::inactive_node_flag_defaults ();
node_flags.read_only = false;
nano::update_flags (node_flags, vm);
@ -671,6 +674,12 @@ std::error_code nano::handle_node_options (boost::program_options::variables_map
nano::rpc_config config{ nano::dev::network_params.network };
config.serialize_toml (toml);
}
else if (type == "log")
{
valid_type = true;
nano::log_config config = nano::log_config::sample_config ();
config.serialize_toml (toml);
}
else if (type == "tls")
{
valid_type = true;
@ -730,7 +739,7 @@ std::error_code nano::handle_node_options (boost::program_options::variables_map
environment.dump (std::cout);
std::stringstream stream;
environment.dump (stream);
inactive_node->node->logger.always_log (stream.str ());
std::cout << stream.str () << std::endl;
}
else
{

View file

@ -1,7 +1,5 @@
#include <nano/lib/logger_mt.hpp>
#include <nano/lib/stats.hpp>
#include <nano/node/confirmation_height_bounded.hpp>
#include <nano/node/logging.hpp>
#include <nano/node/write_database_queue.hpp>
#include <nano/secure/ledger.hpp>
#include <nano/store/block.hpp>
@ -12,11 +10,10 @@
#include <numeric>
nano::confirmation_height_bounded::confirmation_height_bounded (nano::ledger & ledger_a, nano::write_database_queue & write_database_queue_a, std::chrono::milliseconds batch_separate_pending_min_time_a, nano::logging const & logging_a, nano::logger_mt & logger_a, std::atomic<bool> & stopped_a, uint64_t & batch_write_size_a, std::function<void (std::vector<std::shared_ptr<nano::block>> const &)> const & notify_observers_callback_a, std::function<void (nano::block_hash const &)> const & notify_block_already_cemented_observers_callback_a, std::function<uint64_t ()> const & awaiting_processing_size_callback_a) :
nano::confirmation_height_bounded::confirmation_height_bounded (nano::ledger & ledger_a, nano::write_database_queue & write_database_queue_a, std::chrono::milliseconds batch_separate_pending_min_time_a, nano::logger & logger_a, std::atomic<bool> & stopped_a, uint64_t & batch_write_size_a, std::function<void (std::vector<std::shared_ptr<nano::block>> const &)> const & notify_observers_callback_a, std::function<void (nano::block_hash const &)> const & notify_block_already_cemented_observers_callback_a, std::function<uint64_t ()> const & awaiting_processing_size_callback_a) :
ledger (ledger_a),
write_database_queue (write_database_queue_a),
batch_separate_pending_min_time (batch_separate_pending_min_time_a),
logging (logging_a),
logger (logger_a),
stopped (stopped_a),
batch_write_size (batch_write_size_a),
@ -101,9 +98,8 @@ void nano::confirmation_height_bounded::process (std::shared_ptr<nano::block> or
}
else
{
auto error_str = (boost::format ("Ledger mismatch trying to set confirmation height for block %1% (bounded processor)") % current.to_string ()).str ();
logger.always_log (error_str);
std::cerr << error_str << std::endl;
logger.critical (nano::log::type::conf_processor_bounded, "Ledger mismatch trying to set confirmation height for block {} (bounded processor)", current.to_string ());
release_assert (block);
}
}
@ -433,9 +429,8 @@ void nano::confirmation_height_bounded::cement_blocks (nano::write_guard & scope
{
if (!block)
{
auto error_str = (boost::format ("Failed to write confirmation height for block %1% (bounded processor)") % new_cemented_frontier.to_string ()).str ();
logger.always_log (error_str);
std::cerr << error_str << std::endl;
logger.critical (nano::log::type::conf_processor_bounded, "Failed to write confirmation height for block {} (bounded processor)", new_cemented_frontier.to_string ());
// Undo any blocks about to be cemented from this account for this pending write.
cemented_blocks.erase (cemented_blocks.end () - num_blocks_iterated, cemented_blocks.end ());
error = true;
@ -455,10 +450,6 @@ void nano::confirmation_height_bounded::cement_blocks (nano::write_guard & scope
total_blocks_cemented += num_blocks_cemented;
write_confirmation_height (num_blocks_cemented, start_height + total_blocks_cemented - 1, new_cemented_frontier);
transaction.commit ();
if (logging.timing_logging ())
{
logger.always_log (boost::str (boost::format ("Cemented %1% blocks in %2% %3% (bounded processor)") % cemented_blocks.size () % time_spent_cementing % cemented_batch_timer.unit ()));
}
// Update the maximum amount of blocks to write next time based on the time it took to cement this batch.
if (time_spent_cementing > maximum_batch_write_time)
@ -521,11 +512,8 @@ void nano::confirmation_height_bounded::cement_blocks (nano::write_guard & scope
--pending_writes_size;
}
}
auto time_spent_cementing = cemented_batch_timer.since_start ().count ();
if (logging.timing_logging () && time_spent_cementing > 50)
{
logger.always_log (boost::str (boost::format ("Cemented %1% blocks in %2% %3% (bounded processor)") % cemented_blocks.size () % time_spent_cementing % cemented_batch_timer.unit ()));
}
auto time_spent_cementing = cemented_batch_timer.since_start ();
// Scope guard could have been released earlier (0 cemented_blocks would indicate that)
if (scoped_write_guard_a.is_owned () && !cemented_blocks.empty ())
@ -537,7 +525,8 @@ void nano::confirmation_height_bounded::cement_blocks (nano::write_guard & scope
// Bail if there was an error. This indicates that there was a fatal issue with the ledger
// (the blocks probably got rolled back when they shouldn't have).
release_assert (!error);
if (time_spent_cementing > maximum_batch_write_time)
if (time_spent_cementing.count () > maximum_batch_write_time)
{
// Reduce (unless we have hit a floor)
batch_write_size = std::max<uint64_t> (minimum_batch_write_size, batch_write_size - amount_to_change);

View file

@ -1,5 +1,6 @@
#pragma once
#include <nano/lib/logging.hpp>
#include <nano/lib/numbers.hpp>
#include <nano/lib/relaxed_atomic.hpp>
#include <nano/lib/threading.hpp>
@ -11,15 +12,14 @@
namespace nano
{
class ledger;
class logging;
class logger_mt;
class write_database_queue;
class write_guard;
class confirmation_height_bounded final
{
public:
confirmation_height_bounded (nano::ledger &, nano::write_database_queue &, std::chrono::milliseconds batch_separate_pending_min_time, nano::logging const &, nano::logger_mt &, std::atomic<bool> & stopped, uint64_t & batch_write_size, std::function<void (std::vector<std::shared_ptr<nano::block>> const &)> const & cemented_callback, std::function<void (nano::block_hash const &)> const & already_cemented_callback, std::function<uint64_t ()> const & awaiting_processing_size_query);
confirmation_height_bounded (nano::ledger &, nano::write_database_queue &, std::chrono::milliseconds batch_separate_pending_min_time, nano::logger &, std::atomic<bool> & stopped, uint64_t & batch_write_size, std::function<void (std::vector<std::shared_ptr<nano::block>> const &)> const & cemented_callback, std::function<void (nano::block_hash const &)> const & already_cemented_callback, std::function<uint64_t ()> const & awaiting_processing_size_query);
bool pending_empty () const;
void clear_process_vars ();
void process (std::shared_ptr<nano::block> original_block);
@ -121,8 +121,7 @@ private:
nano::ledger & ledger;
nano::write_database_queue & write_database_queue;
std::chrono::milliseconds batch_separate_pending_min_time;
nano::logging const & logging;
nano::logger_mt & logger;
nano::logger & logger;
std::atomic<bool> & stopped;
uint64_t & batch_write_size;
std::function<void (std::vector<std::shared_ptr<nano::block>> const &)> notify_observers_callback;

View file

@ -1,4 +1,3 @@
#include <nano/lib/logger_mt.hpp>
#include <nano/lib/numbers.hpp>
#include <nano/lib/thread_roles.hpp>
#include <nano/lib/utility.hpp>
@ -9,16 +8,16 @@
#include <boost/thread/latch.hpp>
nano::confirmation_height_processor::confirmation_height_processor (nano::ledger & ledger_a, nano::write_database_queue & write_database_queue_a, std::chrono::milliseconds batch_separate_pending_min_time_a, nano::logging const & logging_a, nano::logger_mt & logger_a, boost::latch & latch, confirmation_height_mode mode_a) :
nano::confirmation_height_processor::confirmation_height_processor (nano::ledger & ledger_a, nano::write_database_queue & write_database_queue_a, std::chrono::milliseconds batch_separate_pending_min_time_a, nano::logger & logger_a, boost::latch & latch, confirmation_height_mode mode_a) :
ledger (ledger_a),
write_database_queue (write_database_queue_a),
unbounded_processor (
ledger_a, write_database_queue_a, batch_separate_pending_min_time_a, logging_a, logger_a, stopped, batch_write_size,
ledger_a, write_database_queue_a, batch_separate_pending_min_time_a, logger_a, stopped, batch_write_size,
/* cemented_callback */ [this] (auto & cemented_blocks) { this->notify_cemented (cemented_blocks); },
/* already cemented_callback */ [this] (auto const & block_hash_a) { this->notify_already_cemented (block_hash_a); },
/* awaiting_processing_size_query */ [this] () { return this->awaiting_processing_size (); }),
bounded_processor (
ledger_a, write_database_queue_a, batch_separate_pending_min_time_a, logging_a, logger_a, stopped, batch_write_size,
ledger_a, write_database_queue_a, batch_separate_pending_min_time_a, logger_a, stopped, batch_write_size,
/* cemented_callback */ [this] (auto & cemented_blocks) { this->notify_cemented (cemented_blocks); },
/* already cemented_callback */ [this] (auto const & block_hash_a) { this->notify_already_cemented (block_hash_a); },
/* awaiting_processing_size_query */ [this] () { return this->awaiting_processing_size (); }),

View file

@ -1,5 +1,6 @@
#pragma once
#include <nano/lib/logging.hpp>
#include <nano/lib/numbers.hpp>
#include <nano/lib/timer.hpp>
#include <nano/node/confirmation_height_bounded.hpp>
@ -24,14 +25,14 @@ class latch;
namespace nano
{
class ledger;
class logger_mt;
class write_database_queue;
class confirmation_height_processor final
{
public:
confirmation_height_processor (nano::ledger &, nano::write_database_queue &, std::chrono::milliseconds, nano::logging const &, nano::logger_mt &, boost::latch & initialized_latch, confirmation_height_mode = confirmation_height_mode::automatic);
confirmation_height_processor (nano::ledger &, nano::write_database_queue &, std::chrono::milliseconds, nano::logger &, boost::latch & initialized_latch, confirmation_height_mode = confirmation_height_mode::automatic);
~confirmation_height_processor ();
void pause ();
void unpause ();
void stop ();

View file

@ -1,7 +1,5 @@
#include <nano/lib/logger_mt.hpp>
#include <nano/lib/stats.hpp>
#include <nano/node/confirmation_height_unbounded.hpp>
#include <nano/node/logging.hpp>
#include <nano/node/write_database_queue.hpp>
#include <nano/secure/ledger.hpp>
#include <nano/store/block.hpp>
@ -12,11 +10,10 @@
#include <numeric>
nano::confirmation_height_unbounded::confirmation_height_unbounded (nano::ledger & ledger_a, nano::write_database_queue & write_database_queue_a, std::chrono::milliseconds batch_separate_pending_min_time_a, nano::logging const & logging_a, nano::logger_mt & logger_a, std::atomic<bool> & stopped_a, uint64_t & batch_write_size_a, std::function<void (std::vector<std::shared_ptr<nano::block>> const &)> const & notify_observers_callback_a, std::function<void (nano::block_hash const &)> const & notify_block_already_cemented_observers_callback_a, std::function<uint64_t ()> const & awaiting_processing_size_callback_a) :
nano::confirmation_height_unbounded::confirmation_height_unbounded (nano::ledger & ledger_a, nano::write_database_queue & write_database_queue_a, std::chrono::milliseconds batch_separate_pending_min_time_a, nano::logger & logger_a, std::atomic<bool> & stopped_a, uint64_t & batch_write_size_a, std::function<void (std::vector<std::shared_ptr<nano::block>> const &)> const & notify_observers_callback_a, std::function<void (nano::block_hash const &)> const & notify_block_already_cemented_observers_callback_a, std::function<uint64_t ()> const & awaiting_processing_size_callback_a) :
ledger (ledger_a),
write_database_queue (write_database_queue_a),
batch_separate_pending_min_time (batch_separate_pending_min_time_a),
logging (logging_a),
logger (logger_a),
stopped (stopped_a),
batch_write_size (batch_write_size_a),
@ -77,9 +74,7 @@ void nano::confirmation_height_unbounded::process (std::shared_ptr<nano::block>
}
if (!block)
{
auto error_str = (boost::format ("Ledger mismatch trying to set confirmation height for block %1% (unbounded processor)") % current.to_string ()).str ();
logger.always_log (error_str);
std::cerr << error_str << std::endl;
logger.critical (nano::log::type::conf_processor_unbounded, "Ledger mismatch trying to set confirmation height for block {} (unbounded processor)", current.to_string ());
}
release_assert (block);
@ -395,9 +390,8 @@ void nano::confirmation_height_unbounded::cement_blocks (nano::write_guard & sco
}
else
{
auto error_str = (boost::format ("Failed to write confirmation height for block %1% (unbounded processor)") % pending.hash.to_string ()).str ();
logger.always_log (error_str);
std::cerr << error_str << std::endl;
logger.critical (nano::log::type::conf_processor_unbounded, "Failed to write confirmation height for block {} (unbounded processor)", pending.hash.to_string ());
error = true;
break;
}
@ -424,10 +418,6 @@ void nano::confirmation_height_unbounded::cement_blocks (nano::write_guard & sco
}
auto time_spent_cementing = cemented_batch_timer.since_start ().count ();
if (logging.timing_logging () && time_spent_cementing > 50)
{
logger.always_log (boost::str (boost::format ("Cemented %1% blocks in %2% %3% (unbounded processor)") % cemented_blocks.size () % time_spent_cementing % cemented_batch_timer.unit ()));
}
scoped_write_guard_a.release ();
notify_observers_callback (cemented_blocks);

View file

@ -1,5 +1,6 @@
#pragma once
#include <nano/lib/logging.hpp>
#include <nano/lib/numbers.hpp>
#include <nano/lib/relaxed_atomic.hpp>
#include <nano/lib/threading.hpp>
@ -12,15 +13,14 @@
namespace nano
{
class ledger;
class logging;
class logger_mt;
class write_database_queue;
class write_guard;
class confirmation_height_unbounded final
{
public:
confirmation_height_unbounded (nano::ledger &, nano::write_database_queue &, std::chrono::milliseconds batch_separate_pending_min_time, nano::logging const &, nano::logger_mt &, std::atomic<bool> & stopped, uint64_t & batch_write_size, std::function<void (std::vector<std::shared_ptr<nano::block>> const &)> const & cemented_callback, std::function<void (nano::block_hash const &)> const & already_cemented_callback, std::function<uint64_t ()> const & awaiting_processing_size_query);
confirmation_height_unbounded (nano::ledger &, nano::write_database_queue &, std::chrono::milliseconds batch_separate_pending_min_time, nano::logger &, std::atomic<bool> & stopped, uint64_t & batch_write_size, std::function<void (std::vector<std::shared_ptr<nano::block>> const &)> const & cemented_callback, std::function<void (nano::block_hash const &)> const & already_cemented_callback, std::function<uint64_t ()> const & awaiting_processing_size_query);
bool pending_empty () const;
void clear_process_vars ();
void process (std::shared_ptr<nano::block> original_block);
@ -98,10 +98,9 @@ private:
nano::ledger & ledger;
nano::write_database_queue & write_database_queue;
std::chrono::milliseconds batch_separate_pending_min_time;
nano::logger_mt & logger;
nano::logger & logger;
std::atomic<bool> & stopped;
uint64_t & batch_write_size;
nano::logging const & logging;
std::function<void (std::vector<std::shared_ptr<nano::block>> const &)> notify_observers_callback;
std::function<void (nano::block_hash const &)> notify_block_already_cemented_observers_callback;

View file

@ -94,7 +94,8 @@ void nano::distributed_work::start ()
}
else
{
this_l->node.logger.try_log (boost::str (boost::format ("Error resolving work peer: %1%:%2%: %3%") % peer.first % peer.second % ec.message ()));
this_l->node.logger.error (nano::log::type::distributed_work, "Error resolving work peer: {}:{} ({})", peer.first, peer.second, ec.message ());
this_l->failure ();
}
});
@ -166,7 +167,11 @@ void nano::distributed_work::do_request (nano::tcp_endpoint const & endpoint_a)
}
else if (ec)
{
this_l->node.logger.try_log (boost::str (boost::format ("Work peer responded with an error %1% %2%: %3%") % connection->endpoint.address () % connection->endpoint.port () % connection->response.result ()));
this_l->node.logger.error (nano::log::type::distributed_work, "Work peer responded with an error {}:{} ({})",
nano::util::to_str (connection->endpoint.address ()),
connection->endpoint.port (),
ec.message ());
this_l->add_bad_peer (connection->endpoint);
this_l->failure ();
}
@ -180,7 +185,11 @@ void nano::distributed_work::do_request (nano::tcp_endpoint const & endpoint_a)
}
else if (ec && ec != boost::system::errc::operation_canceled)
{
this_l->node.logger.try_log (boost::str (boost::format ("Unable to write to work_peer %1% %2%: %3% (%4%)") % connection->endpoint.address () % connection->endpoint.port () % ec.message () % ec.value ()));
this_l->node.logger.error (nano::log::type::distributed_work, "Unable to write to work peer {}:{} ({})",
nano::util::to_str (connection->endpoint.address ()),
connection->endpoint.port (),
ec.message ());
this_l->add_bad_peer (connection->endpoint);
this_l->failure ();
}
@ -188,7 +197,11 @@ void nano::distributed_work::do_request (nano::tcp_endpoint const & endpoint_a)
}
else if (ec && ec != boost::system::errc::operation_canceled)
{
this_l->node.logger.try_log (boost::str (boost::format ("Unable to connect to work_peer %1% %2%: %3% (%4%)") % connection->endpoint.address () % connection->endpoint.port () % ec.message () % ec.value ()));
this_l->node.logger.error (nano::log::type::distributed_work, "Unable to connect to work peer {}:{} ({})",
nano::util::to_str (connection->endpoint.address ()),
connection->endpoint.port (),
ec.message ());
this_l->add_bad_peer (connection->endpoint);
this_l->failure ();
}
@ -219,7 +232,10 @@ void nano::distributed_work::do_cancel (nano::tcp_endpoint const & endpoint_a)
[this_l, peer_cancel, cancelling_l] (boost::system::error_code const & ec, std::size_t bytes_transferred) {
if (ec && ec != boost::system::errc::operation_canceled)
{
this_l->node.logger.try_log (boost::str (boost::format ("Unable to send work_cancel to work_peer %1% %2%: %3% (%4%)") % cancelling_l->endpoint.address () % cancelling_l->endpoint.port () % ec.message () % ec.value ()));
this_l->node.logger.error (nano::log::type::distributed_work, "Unable to send work cancel to work peer {}:{} ({})",
nano::util::to_str (cancelling_l->endpoint.address ()),
cancelling_l->endpoint.port (),
ec.message ());
}
}));
}
@ -247,17 +263,28 @@ void nano::distributed_work::success (std::string const & body_a, nano::tcp_endp
}
else
{
node.logger.try_log (boost::str (boost::format ("Incorrect work response from %1%:%2% for root %3% with diffuculty %4%: %5%") % endpoint_a.address () % endpoint_a.port () % request.root.to_string () % nano::to_string_hex (request.difficulty) % work_text));
node.logger.error (nano::log::type::distributed_work, "Incorrect work response from {}:{} for root {} with diffuculty {}: {}",
nano::util::to_str (endpoint_a.address ()),
endpoint_a.port (),
request.root.to_string (),
nano::to_string_hex (request.difficulty),
work_text);
}
}
else
{
node.logger.try_log (boost::str (boost::format ("Work response from %1%:%2% wasn't a number: %3%") % endpoint_a.address () % endpoint_a.port () % work_text));
node.logger.error (nano::log::type::distributed_work, "Work response from {}:{} wasn't a number: {}",
nano::util::to_str (endpoint_a.address ()),
endpoint_a.port (),
work_text);
}
}
catch (...)
{
node.logger.try_log (boost::str (boost::format ("Work response from %1%:%2% wasn't parsable: %3%") % endpoint_a.address () % endpoint_a.port () % body_a));
node.logger.error (nano::log::type::distributed_work, "Work response from {}:{} wasn't parsable: {}",
nano::util::to_str (endpoint_a.address ()),
endpoint_a.port (),
body_a);
}
if (error)
{
@ -290,12 +317,18 @@ void nano::distributed_work::stop_once (bool const local_stop_a)
connection_l->socket.close (ec);
if (ec)
{
this_l->node.logger.try_log (boost::str (boost::format ("Error closing socket with work_peer %1% %2%: %3%") % connection_l->endpoint.address () % connection_l->endpoint.port () % ec.message () % ec.value ()));
this_l->node.logger.error (nano::log::type::distributed_work, "Error closing socket with work peer: {}:{} ({})",
nano::util::to_str (connection_l->endpoint.address ()),
connection_l->endpoint.port (),
ec.message ());
}
}
else
{
this_l->node.logger.try_log (boost::str (boost::format ("Error cancelling operation with work_peer %1% %2%: %3%") % connection_l->endpoint.address () % connection_l->endpoint.port () % ec.message () % ec.value ()));
this_l->node.logger.error (nano::log::type::distributed_work, "Error cancelling operation with work peer: {}:{} ({})",
nano::util::to_str (connection_l->endpoint.address ()),
connection_l->endpoint.port (),
ec.message ());
}
}
}));
@ -310,6 +343,13 @@ void nano::distributed_work::set_once (uint64_t const work_a, std::string const
if (!finished.exchange (true))
{
elapsed.stop ();
node.logger.info (nano::log::type::distributed_work, "Work generation for {}, with a threshold difficulty of {} (multiplier {}x) complete: {} ms",
request.root.to_string (),
nano::to_string_hex (request.difficulty),
nano::to_string (nano::difficulty::to_multiplier (request.difficulty, node.default_difficulty (request.version)), 2),
elapsed.value ().count ());
status = work_generation_status::success;
if (request.callback)
{
@ -317,12 +357,6 @@ void nano::distributed_work::set_once (uint64_t const work_a, std::string const
}
winner = source_a;
work_result = work_a;
if (node.config.logging.work_generation_time ())
{
boost::format unformatted_l ("Work generation for %1%, with a threshold difficulty of %2% (multiplier %3%x) complete: %4% ms");
auto multiplier_text_l (nano::to_string (nano::difficulty::to_multiplier (request.difficulty, node.default_difficulty (request.version)), 2));
node.logger.try_log (boost::str (unformatted_l % request.root.to_string () % nano::to_string_hex (request.difficulty) % multiplier_text_l % elapsed.value ().count ()));
}
}
}
@ -331,16 +365,17 @@ void nano::distributed_work::cancel ()
if (!finished.exchange (true))
{
elapsed.stop ();
node.logger.info (nano::log::type::distributed_work, "Work generation for {} was cancelled after {} ms",
request.root.to_string (),
elapsed.value ().count ());
status = work_generation_status::cancelled;
if (request.callback)
{
request.callback (boost::none);
}
stop_once (true);
if (node.config.logging.work_generation_time ())
{
node.logger.try_log (boost::str (boost::format ("Work generation for %1% was cancelled after %2% ms") % request.root.to_string () % elapsed.value ().count ()));
}
}
}
@ -359,11 +394,12 @@ void nano::distributed_work::handle_failure ()
node.unresponsive_work_peers = true;
if (!local_generation_started && !finished.exchange (true))
{
node.logger.info (nano::log::type::distributed_work, "Work peer(s) failed to generate work for root {}, retrying... (backoff: {}s)",
request.root.to_string (),
backoff.count ());
status = work_generation_status::failure_peers;
if (backoff == std::chrono::seconds (1) && node.config.logging.work_generation_time ())
{
node.logger.always_log ("Work peer(s) failed to generate work for root ", request.root.to_string (), ", retrying...");
}
auto now (std::chrono::steady_clock::now ());
std::weak_ptr<nano::node> node_weak (node.shared ());
auto next_backoff (std::min (backoff * 2, std::chrono::seconds (5 * 60)));

View file

@ -250,10 +250,6 @@ bool nano::election::transition_time (nano::confirmation_solicitor & solicitor_a
if (!state_change (state_m, nano::election::state_t::expired_unconfirmed))
{
result = true; // Return true to indicate this election should be cleaned up
if (node.config.logging.election_expiration_tally_logging ())
{
log_votes (tally_impl (), "Election expired: ");
}
status.type = nano::election_status_type::stopped;
}
}
@ -375,10 +371,6 @@ void nano::election::confirm_if_quorum (nano::unique_lock<nano::mutex> & lock_a)
}
if (!node.ledger.cache.final_votes_confirmation_canary.load () || final_weight >= node.online_reps.delta ())
{
if (node.config.logging.vote_logging () || (node.config.logging.election_fork_tally_logging () && last_blocks.size () > 1))
{
log_votes (tally_l);
}
confirm_once (lock_a, nano::election_status_type::active_confirmed_quorum);
}
}
@ -419,25 +411,6 @@ nano::election_status nano::election::set_status_type (nano::election_status_typ
return status_l;
}
void nano::election::log_votes (nano::tally_t const & tally_a, std::string const & prefix_a) const
{
std::stringstream tally;
std::string line_end (node.config.logging.single_line_record () ? "\t" : "\n");
tally << boost::str (boost::format ("%1%%2%Vote tally for root %3%, final weight:%4%") % prefix_a % line_end % root.to_string () % final_weight);
for (auto i (tally_a.begin ()), n (tally_a.end ()); i != n; ++i)
{
tally << boost::str (boost::format ("%1%Block %2% weight %3%") % line_end % i->second->hash ().to_string () % i->first.convert_to<std::string> ());
}
for (auto i (last_votes.begin ()), n (last_votes.end ()); i != n; ++i)
{
if (i->first != nullptr)
{
tally << boost::str (boost::format ("%1%%2% %3% %4%") % line_end % i->first.to_account () % std::to_string (i->second.timestamp) % i->second.hash.to_string ());
}
}
node.logger.try_log (tally.str ());
}
std::shared_ptr<nano::block> nano::election::find (nano::block_hash const & hash_a) const
{
std::shared_ptr<nano::block> result;

View file

@ -1,5 +1,6 @@
#pragma once
#include <nano/lib/logging.hpp>
#include <nano/secure/common.hpp>
#include <nano/secure/ledger.hpp>
#include <nano/store/component.hpp>
@ -62,6 +63,9 @@ enum class election_behavior
nano::stat::detail to_stat_detail (nano::election_behavior);
// map of vote weight per block, ordered greater first
using tally_t = std::map<nano::uint128_t, std::shared_ptr<nano::block>, std::greater<nano::uint128_t>>;
struct election_extended_status final
{
nano::election_status status;
@ -120,7 +124,6 @@ public: // Status
std::shared_ptr<nano::block> winner () const;
std::atomic<unsigned> confirmation_request_count{ 0 };
void log_votes (nano::tally_t const &, std::string const & = "") const;
nano::tally_t tally () const;
bool have_quorum (nano::tally_t const &) const;

View file

@ -2,7 +2,7 @@
#include <nano/node/epoch_upgrader.hpp>
#include <nano/node/node.hpp>
nano::epoch_upgrader::epoch_upgrader (nano::node & node_a, nano::ledger & ledger_a, nano::store::component & store_a, nano::network_params & network_params_a, nano::logger_mt & logger_a) :
nano::epoch_upgrader::epoch_upgrader (nano::node & node_a, nano::ledger & ledger_a, nano::store::component & store_a, nano::network_params & network_params_a, nano::logger & logger_a) :
node{ node_a },
ledger{ ledger_a },
store{ store_a },
@ -59,7 +59,12 @@ void nano::epoch_upgrader::upgrade_impl (nano::raw_key const & prv_a, nano::epoc
else
{
bool fork (result == nano::process_result::fork);
logger.always_log (boost::str (boost::format ("Failed to upgrade account %1%. Valid signature: %2%. Valid work: %3%. Block processor fork: %4%") % account_a.to_account () % valid_signature % valid_work % fork));
logger.error (nano::log::type::epoch_upgrader, "Failed to upgrade account {} (valid signature: {}, valid work: {}, fork: {})",
account_a.to_account (),
valid_signature,
valid_work,
fork);
}
};
@ -181,12 +186,16 @@ void nano::epoch_upgrader::upgrade_impl (nano::raw_key const & prv_a, nano::epoc
if (!accounts_list.empty ())
{
logger.always_log (boost::str (boost::format ("%1% accounts were upgraded to new epoch, %2% remain...") % total_upgraded_accounts % (accounts_list.size () - upgraded_accounts)));
logger.info (nano::log::type::epoch_upgrader, "{} accounts were upgraded to new epoch, {} remain...",
total_upgraded_accounts,
accounts_list.size () - upgraded_accounts);
accounts_list.clear ();
}
else
{
logger.always_log (boost::str (boost::format ("%1% total accounts were upgraded to new epoch") % total_upgraded_accounts));
logger.info (nano::log::type::epoch_upgrader, "{} total accounts were upgraded to new epoch", total_upgraded_accounts);
finished_accounts = true;
}
}
@ -284,11 +293,12 @@ void nano::epoch_upgrader::upgrade_impl (nano::raw_key const & prv_a, nano::epoc
// Repeat if some pending accounts were upgraded
if (upgraded_pending != 0)
{
logger.always_log (boost::str (boost::format ("%1% unopened accounts with pending blocks were upgraded to new epoch...") % total_upgraded_pending));
logger.info (nano::log::type::epoch_upgrader, "{} unopened accounts with pending blocks were upgraded to new epoch...", total_upgraded_pending);
}
else
{
logger.always_log (boost::str (boost::format ("%1% total unopened accounts with pending blocks were upgraded to new epoch") % total_upgraded_pending));
logger.info (nano::log::type::epoch_upgrader, "{} total unopened accounts with pending blocks were upgraded to new epoch", total_upgraded_pending);
finished_pending = true;
}
}
@ -296,5 +306,5 @@ void nano::epoch_upgrader::upgrade_impl (nano::raw_key const & prv_a, nano::epoc
finished_upgrade = (total_upgraded_accounts == 0) && (total_upgraded_pending == 0);
}
logger.always_log ("Epoch upgrade is completed");
logger.info (nano::log::type::epoch_upgrader, "Epoch upgrade is completed");
}

View file

@ -2,6 +2,7 @@
#include <nano/lib/epoch.hpp>
#include <nano/lib/locks.hpp>
#include <nano/lib/logging.hpp>
#include <nano/lib/numbers.hpp>
#include <future>
@ -15,12 +16,11 @@ namespace store
class component;
}
class network_params;
class logger_mt;
class epoch_upgrader final
{
public:
epoch_upgrader (nano::node &, nano::ledger &, nano::store::component &, nano::network_params &, nano::logger_mt &);
epoch_upgrader (nano::node &, nano::ledger &, nano::store::component &, nano::network_params &, nano::logger &);
bool start (nano::raw_key const & prv, nano::epoch epoch, uint64_t count_limit, uint64_t threads);
void stop ();
@ -30,7 +30,7 @@ private: // Dependencies
nano::ledger & ledger;
nano::store::component & store;
nano::network_params & network_params;
nano::logger_mt & logger;
nano::logger & logger;
private:
void upgrade_impl (nano::raw_key const & prv, nano::epoch epoch, uint64_t count_limit, uint64_t threads);

View file

@ -100,7 +100,7 @@ void nano::gap_cache::bootstrap_start (nano::block_hash const & hash_a)
{
if (!node_l->bootstrap_initiator.in_progress ())
{
node_l->logger.try_log (boost::str (boost::format ("Missing block %1% which has enough votes to warrant lazy bootstrapping it") % hash_a.to_string ()));
node_l->logger.debug (nano::log::type::gap_cache, "Block {} has enough votes to warrant lazy bootstrapping it", hash_a.to_string ());
}
if (!node_l->flags.disable_lazy_bootstrap)
{

View file

@ -65,13 +65,13 @@ void nano::ipc::broker::start ()
}
catch (nano::error const & err)
{
this_l->node.logger.always_log ("IPC: could not broadcast message: ", err.get_message ());
this_l->node.logger.error (nano::log::type::ipc, "Could not broadcast message: {}", err.get_message ());
}
});
}
template <typename COLL, typename TOPIC_TYPE>
void subscribe_or_unsubscribe (nano::logger_mt & logger, COLL & subscriber_collection, std::weak_ptr<nano::ipc::subscriber> const & subscriber_a, TOPIC_TYPE topic_a)
void subscribe_or_unsubscribe (nano::logger & logger, COLL & subscriber_collection, std::weak_ptr<nano::ipc::subscriber> const & subscriber_a, TOPIC_TYPE topic_a)
{
// Evict subscribers from dead sessions. Also remove current subscriber if unsubscribing.
subscriber_collection.erase (std::remove_if (subscriber_collection.begin (), subscriber_collection.end (),
@ -85,7 +85,7 @@ void subscribe_or_unsubscribe (nano::logger_mt & logger, COLL & subscriber_colle
remove = topic_a->unsubscribe && subscriber_l->get_id () == calling_subscriber_l->get_id ();
if (remove)
{
logger.always_log ("IPC: unsubscription from subscriber #", calling_subscriber_l->get_id ());
logger.info (nano::log::type::ipc, "Subscriber ubsubscribed #{}", calling_subscriber_l->get_id ());
}
}
}

View file

@ -23,8 +23,6 @@
#include <flatbuffers/flatbuffers.h>
using namespace boost::log;
namespace
{
/**
@ -39,10 +37,7 @@ public:
server (server_a), node (server_a.node), session_id (server_a.id_dispenser.fetch_add (1)),
io_ctx (io_ctx_a), strand (io_ctx_a.get_executor ()), socket (io_ctx_a), config_transport (config_transport_a)
{
if (node.config.logging.log_ipc ())
{
node.logger.always_log ("IPC: created session with id: ", session_id.load ());
}
node.logger.debug (nano::log::type::ipc, "Creating session with id: ", session_id.load ());
}
~session ()
@ -234,10 +229,7 @@ public:
this_l->timer_cancel ();
if (ec == boost::asio::error::broken_pipe || ec == boost::asio::error::connection_aborted || ec == boost::asio::error::connection_reset || ec == boost::asio::error::connection_refused)
{
if (this_l->node.config.logging.log_ipc ())
{
this_l->node.logger.always_log (boost::str (boost::format ("IPC: error reading %1% ") % ec.message ()));
}
this_l->node.logger.error (nano::log::type::ipc, "Error reading: ", ec.message ());
}
else if (bytes_transferred_a > 0)
{
@ -260,10 +252,11 @@ public:
auto buffer (std::make_shared<std::vector<uint8_t>> ());
buffer->insert (buffer->end (), reinterpret_cast<std::uint8_t *> (&big), reinterpret_cast<std::uint8_t *> (&big) + sizeof (std::uint32_t));
buffer->insert (buffer->end (), body.begin (), body.end ());
if (this_l->node.config.logging.log_ipc ())
{
this_l->node.logger.always_log (boost::str (boost::format ("IPC/RPC request %1% completed in: %2% %3%") % request_id_l % this_l->session_timer.stop ().count () % this_l->session_timer.unit ()));
}
this_l->node.logger.debug (nano::log::type::ipc, "IPC/RPC request {} completed in: {} {}",
request_id_l,
this_l->session_timer.stop ().count (),
this_l->session_timer.unit ());
this_l->timer_start (std::chrono::seconds (this_l->config_transport.io_timeout));
this_l->queued_write (boost::asio::buffer (buffer->data (), buffer->size ()), [this_l, buffer] (boost::system::error_code const & error_a, std::size_t size_a) {
@ -272,9 +265,9 @@ public:
{
this_l->read_next_request ();
}
else if (this_l->node.config.logging.log_ipc ())
else
{
this_l->node.logger.always_log ("IPC: Write failed: ", error_a.message ());
this_l->node.logger.error (nano::log::type::ipc, "Write failed: ", error_a.message ());
}
});
@ -307,10 +300,7 @@ public:
this_l->active_encoding = static_cast<nano::ipc::payload_encoding> (encoding);
if (this_l->buffer[nano::ipc::preamble_offset::lead] != 'N' || this_l->buffer[nano::ipc::preamble_offset::reserved_1] != 0 || this_l->buffer[nano::ipc::preamble_offset::reserved_2] != 0)
{
if (this_l->node.config.logging.log_ipc ())
{
this_l->node.logger.always_log ("IPC: Invalid preamble");
}
this_l->node.logger.error (nano::log::type::ipc, "Invalid preamble");
}
else if (encoding == static_cast<uint8_t> (nano::ipc::payload_encoding::json_v1) || encoding == static_cast<uint8_t> (nano::ipc::payload_encoding::json_v1_unsafe))
{
@ -344,10 +334,9 @@ public:
if (encoding == static_cast<uint8_t> (nano::ipc::payload_encoding::flatbuffers_json))
{
this_l->flatbuffers_handler->process_json (this_l->buffer.data (), this_l->buffer_size, [this_l] (std::shared_ptr<std::string> const & body) {
if (this_l->node.config.logging.log_ipc ())
{
this_l->node.logger.always_log (boost::str (boost::format ("IPC/Flatbuffer request completed in: %1% %2%") % this_l->session_timer.stop ().count () % this_l->session_timer.unit ()));
}
this_l->node.logger.debug (nano::log::type::ipc, "IPC/Flatbuffer request completed in: {} {}",
this_l->session_timer.stop ().count (),
this_l->session_timer.unit ());
auto big_endian_length = std::make_shared<uint32_t> (boost::endian::native_to_big (static_cast<uint32_t> (body->size ())));
boost::array<boost::asio::const_buffer, 2> buffers = {
@ -360,9 +349,9 @@ public:
{
this_l->read_next_request ();
}
else if (this_l->node.config.logging.log_ipc ())
else
{
this_l->node.logger.always_log ("IPC: Write failed: ", error_a.message ());
this_l->node.logger.error (nano::log::type::ipc, "Write failed: {}", error_a.message ());
}
});
});
@ -370,10 +359,9 @@ public:
else
{
this_l->flatbuffers_handler->process (this_l->buffer.data (), this_l->buffer_size, [this_l] (std::shared_ptr<flatbuffers::FlatBufferBuilder> const & fbb) {
if (this_l->node.config.logging.log_ipc ())
{
this_l->node.logger.always_log (boost::str (boost::format ("IPC/Flatbuffer request completed in: %1% %2%") % this_l->session_timer.stop ().count () % this_l->session_timer.unit ()));
}
this_l->node.logger.debug (nano::log::type::ipc, "IPC/Flatbuffer request completed in: {} {}",
this_l->session_timer.stop ().count (),
this_l->session_timer.unit ());
auto big_endian_length = std::make_shared<uint32_t> (boost::endian::native_to_big (static_cast<uint32_t> (fbb->GetSize ())));
boost::array<boost::asio::const_buffer, 2> buffers = {
@ -386,9 +374,9 @@ public:
{
this_l->read_next_request ();
}
else if (this_l->node.config.logging.log_ipc ())
else
{
this_l->node.logger.always_log ("IPC: Write failed: ", error_a.message ());
this_l->node.logger.error (nano::log::type::ipc, "Write failed: {}", error_a.message ());
}
});
});
@ -396,9 +384,9 @@ public:
});
});
}
else if (this_l->node.config.logging.log_ipc ())
else
{
this_l->node.logger.always_log ("IPC: Unsupported payload encoding");
this_l->node.logger.error (nano::log::type::ipc, "Unsupported payload encoding");
}
});
}
@ -523,7 +511,7 @@ public:
}
else
{
node->logger.always_log ("IPC: acceptor error: ", ec.message ());
node->logger.error (nano::log::type::ipc, "Acceptor error: ", ec.message ());
}
if (ec != boost::asio::error::operation_aborted && acceptor->is_open ())
@ -532,7 +520,7 @@ public:
}
else
{
node->logger.always_log ("IPC: shutting down");
node->logger.info (nano::log::type::ipc, "Shutting down");
}
});
}
@ -625,7 +613,7 @@ nano::ipc::ipc_server::ipc_server (nano::node & node_a, nano::node_rpc_config co
boost::asio::local::stream_protocol::endpoint ep{ node_a.config.ipc_config.transport_domain.path };
transports.push_back (std::make_shared<domain_socket_transport> (*this, ep, node_a.config.ipc_config.transport_domain, threads));
#else
node.logger.always_log ("IPC: Domain sockets are not supported on this platform");
node.logger.error (nano::log::type::ipc_server, "Domain sockets are not supported on this platform");
#endif
}
@ -635,7 +623,7 @@ nano::ipc::ipc_server::ipc_server (nano::node & node_a, nano::node_rpc_config co
transports.push_back (std::make_shared<tcp_socket_transport> (*this, boost::asio::ip::tcp::endpoint (boost::asio::ip::tcp::v6 (), node_a.config.ipc_config.transport_tcp.port), node_a.config.ipc_config.transport_tcp, threads));
}
node.logger.always_log ("IPC: server started");
node.logger.debug (nano::log::type::ipc_server, "Server started");
if (!transports.empty ())
{
@ -644,13 +632,13 @@ nano::ipc::ipc_server::ipc_server (nano::node & node_a, nano::node_rpc_config co
}
catch (std::runtime_error const & ex)
{
node.logger.always_log ("IPC: ", ex.what ());
node.logger.error (nano::log::type::ipc_server, "Error: {}", ex.what ());
}
}
nano::ipc::ipc_server::~ipc_server ()
{
node.logger.always_log ("IPC: server stopped");
node.logger.debug (nano::log::type::ipc_server, "Server stopped");
}
void nano::ipc::ipc_server::stop ()
@ -690,9 +678,7 @@ nano::error nano::ipc::ipc_server::reload_access_config ()
nano::error access_config_error (nano::ipc::read_access_config_toml (node.application_path, access));
if (access_config_error)
{
auto error (boost::str (boost::format ("IPC: invalid access configuration file: %1%") % access_config_error.get_message ()));
std::cerr << error << std::endl;
node.logger.always_log (error);
node.logger.error (nano::log::type::ipc_server, "Invalid access configuration file: {}", access_config_error.get_message ());
}
return access_config_error;
}

View file

@ -2955,7 +2955,7 @@ void nano::json_handler::password_change ()
rpc_l->response_l.put ("changed", error ? "0" : "1");
if (!error)
{
rpc_l->node.logger.try_log ("Wallet password changed");
rpc_l->node.logger.warn (nano::log::type::rpc, "Wallet password changed");
}
}
}
@ -4773,7 +4773,8 @@ void nano::json_handler::wallet_lock ()
empty.clear ();
wallet->store.password.value_set (empty);
response_l.put ("locked", "1");
node.logger.try_log ("Wallet locked");
node.logger.warn (nano::log::type::rpc, "Wallet locked");
}
response_errors ();
}

View file

@ -1,344 +0,0 @@
#include <nano/lib/config.hpp>
#include <nano/lib/jsonconfig.hpp>
#include <nano/lib/logger_mt.hpp>
#include <nano/lib/tomlconfig.hpp>
#include <nano/node/logging.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/log/expressions.hpp>
#include <boost/log/utility/exception_handler.hpp>
#include <boost/log/utility/setup/common_attributes.hpp>
#include <boost/log/utility/setup/console.hpp>
#include <boost/log/utility/setup/file.hpp>
#ifdef BOOST_WINDOWS
#else
#define BOOST_LOG_USE_NATIVE_SYSLOG
#include <boost/log/sinks/syslog_backend.hpp>
#endif
BOOST_LOG_ATTRIBUTE_KEYWORD (severity, "Severity", nano::severity_level)
boost::shared_ptr<boost::log::sinks::synchronous_sink<boost::log::sinks::text_file_backend>> nano::logging::file_sink;
std::atomic_flag nano::logging::logging_already_added ATOMIC_FLAG_INIT;
void nano::logging::init (std::filesystem::path const & application_path_a)
{
if (!logging_already_added.test_and_set ())
{
boost::log::add_common_attributes ();
auto format = boost::log::expressions::stream << boost::log::expressions::attr<severity_level, severity_tag> ("Severity") << boost::log::expressions::smessage;
auto format_with_timestamp = boost::log::expressions::stream << "[" << boost::log::expressions::attr<boost::posix_time::ptime> ("TimeStamp") << "]: " << boost::log::expressions::attr<severity_level, severity_tag> ("Severity") << boost::log::expressions::smessage;
if (log_to_cerr ())
{
boost::log::add_console_log (std::cerr, boost::log::keywords::format = format_with_timestamp);
}
#ifdef BOOST_WINDOWS
#else
static auto sys_sink = boost::make_shared<boost::log::sinks::synchronous_sink<boost::log::sinks::syslog_backend>> (boost::log::keywords::facility = boost::log::sinks::syslog::user, boost::log::keywords::use_impl = boost::log::sinks::syslog::impl_types::native);
sys_sink->set_formatter (format);
// Currently only mapping sys log errors
boost::log::sinks::syslog::custom_severity_mapping<nano::severity_level> mapping ("Severity");
mapping[nano::severity_level::error] = boost::log::sinks::syslog::error;
sys_sink->locked_backend ()->set_severity_mapper (mapping);
// Only allow messages or error or greater severity to the sys log
sys_sink->set_filter (severity >= nano::severity_level::error);
boost::log::core::get ()->add_sink (sys_sink);
#endif
//clang-format off
#if BOOST_VERSION < 107000
if (stable_log_filename)
{
stable_log_filename = false;
std::cerr << "The stable_log_filename config setting is only available when building with Boost 1.70 or later. Reverting to old behavior." << std::endl;
}
#endif
auto path = application_path_a / "log";
if (stable_log_filename)
{
#if BOOST_VERSION >= 107000
auto const file_name = path / "node.log";
// Logging to node.log and node_<pattern> instead of log_<pattern>.log is deliberate. This way,
// existing log monitoring scripts expecting the old logfile structure will fail immediately instead
// of reading only rotated files with old entries.
file_sink = boost::log::add_file_log (boost::log::keywords::target = path,
boost::log::keywords::file_name = file_name,
boost::log::keywords::target_file_name = path / "node_%Y-%m-%d_%H-%M-%S.%N.log",
boost::log::keywords::open_mode = std::ios_base::out | std::ios_base::app, // append to node.log if it exists
boost::log::keywords::enable_final_rotation = false, // for stable log filenames, don't rotate on destruction
boost::log::keywords::rotation_size = rotation_size, // max file size in bytes before rotation
boost::log::keywords::auto_flush = flush,
boost::log::keywords::scan_method = boost::log::sinks::file::scan_method::scan_matching,
boost::log::keywords::max_size = max_size, // max total size in bytes of all log files
boost::log::keywords::format = format_with_timestamp);
if (!std::filesystem::exists (file_name))
{
// Create temp stream to first create the file
std::ofstream stream (file_name.string ());
}
// Set permissions before opening otherwise Windows only has read permissions
nano::set_secure_perm_file (file_name);
#else
debug_assert (false);
#endif
}
else
{
file_sink = boost::log::add_file_log (boost::log::keywords::target = path,
boost::log::keywords::file_name = path / "log_%Y-%m-%d_%H-%M-%S.%N.log",
boost::log::keywords::rotation_size = rotation_size,
boost::log::keywords::auto_flush = flush,
boost::log::keywords::scan_method = boost::log::sinks::file::scan_method::scan_matching,
boost::log::keywords::max_size = max_size,
boost::log::keywords::format = format_with_timestamp);
}
struct exception_handler
{
void operator() (std::exception const & e) const
{
std::cerr << "Logging exception: " << e.what () << std::endl;
}
};
boost::log::core::get ()->set_exception_handler (boost::log::make_exception_handler<std::exception> (exception_handler ()));
}
//clang-format on
}
void nano::logging::release_file_sink ()
{
if (logging_already_added.test_and_set ())
{
boost::log::core::get ()->remove_sink (nano::logging::file_sink);
nano::logging::file_sink.reset ();
logging_already_added.clear ();
}
}
nano::error nano::logging::serialize_toml (nano::tomlconfig & toml) const
{
toml.put ("ledger", ledger_logging_value, "Log ledger related messages.\ntype:bool");
toml.put ("ledger_duplicate", ledger_duplicate_logging_value, "Log when a duplicate block is attempted inserted into the ledger.\ntype:bool");
toml.put ("ledger_rollback", election_fork_tally_logging_value, "Log when a block is replaced in the ledger.\ntype:bool");
toml.put ("vote", vote_logging_value, "Vote logging. Enabling this option leads to a high volume.\nof log messages which may affect node performance.\ntype:bool");
toml.put ("rep_crawler", rep_crawler_logging_value, "Rep crawler logging. Enabling this option leads to a high volume.\nof log messages which may affect node performance.\ntype:bool");
toml.put ("election_expiration", election_expiration_tally_logging_value, "Log election tally on expiration.\ntype:bool");
toml.put ("election_fork", election_fork_tally_logging_value, "Log election tally when more than one block is seen.\ntype:bool");
toml.put ("network", network_logging_value, "Log network related messages.\ntype:bool");
toml.put ("network_timeout", network_timeout_logging_value, "Log TCP timeouts.\ntype:bool");
toml.put ("network_message", network_message_logging_value, "Log network errors and message details.\ntype:bool");
toml.put ("network_publish", network_publish_logging_value, "Log publish related network messages.\ntype:bool");
toml.put ("network_packet", network_packet_logging_value, "Log network packet activity.\ntype:bool");
toml.put ("network_keepalive", network_keepalive_logging_value, "Log keepalive related messages.\ntype:bool");
toml.put ("network_node_id_handshake", network_node_id_handshake_logging_value, "Log node-id handshake related messages.\ntype:bool");
toml.put ("network_telemetry", network_telemetry_logging_value, "Log telemetry related messages.\ntype:bool");
toml.put ("network_rejected", network_rejected_logging_value, "Log message when a connection is rejected.\ntype:bool");
toml.put ("node_lifetime_tracing", node_lifetime_tracing_value, "Log node startup and shutdown messages.\ntype:bool");
toml.put ("insufficient_work", insufficient_work_logging_value, "Log if insufficient work is detected.\ntype:bool");
toml.put ("log_ipc", log_ipc_value, "Log IPC related activity.\ntype:bool");
toml.put ("bulk_pull", bulk_pull_logging_value, "Log bulk pull errors and messages.\ntype:bool");
toml.put ("work_generation_time", work_generation_time_value, "Log work generation timing information.\ntype:bool");
toml.put ("upnp_details", upnp_details_logging_value, "Log UPNP discovery details..\nWarning: this may include information.\nabout discovered devices, such as product identification. Please review before sharing logs.\ntype:bool");
toml.put ("timing", timing_logging_value, "Log detailed timing information for various node operations.\ntype:bool");
toml.put ("active_update", active_update_value, "Log when a block is updated while in active transactions.\ntype:bool");
toml.put ("election_result", election_result_logging_value, "Log election result when cleaning up election from active election container.\ntype:bool");
toml.put ("log_to_cerr", log_to_cerr_value, "Log to standard error in addition to the log file. Not recommended for production systems.\ntype:bool");
toml.put ("max_size", max_size, "Maximum log file size in bytes.\ntype:uint64");
toml.put ("rotation_size", rotation_size, "Log file rotation size in character count.\ntype:uint64");
toml.put ("flush", flush, "If enabled, immediately flush new entries to log file.\nWarning: this may negatively affect logging performance.\ntype:bool");
toml.put ("min_time_between_output", min_time_between_log_output.count (), "Minimum time that must pass for low priority entries to be logged.\nWarning: decreasing this value may result in a very large amount of logs.\ntype:milliseconds");
toml.put ("single_line_record", single_line_record_value, "Keep log entries on single lines.\ntype:bool");
toml.put ("stable_log_filename", stable_log_filename, "Append to log/node.log without a timestamp in the filename.\nThe file is not emptied on startup if it exists, but appended to.\ntype:bool");
return toml.get_error ();
}
nano::error nano::logging::deserialize_toml (nano::tomlconfig & toml)
{
toml.get<bool> ("ledger", ledger_logging_value);
toml.get<bool> ("ledger_duplicate", ledger_duplicate_logging_value);
toml.get<bool> ("ledger_rollback", ledger_rollback_logging_value);
toml.get<bool> ("vote", vote_logging_value);
toml.get<bool> ("rep_crawler", rep_crawler_logging_value);
toml.get<bool> ("election_expiration", election_expiration_tally_logging_value);
toml.get<bool> ("election_fork", election_fork_tally_logging_value);
toml.get<bool> ("network", network_logging_value);
toml.get<bool> ("network_timeout", network_timeout_logging_value);
toml.get<bool> ("network_message", network_message_logging_value);
toml.get<bool> ("network_publish", network_publish_logging_value);
toml.get<bool> ("network_packet", network_packet_logging_value);
toml.get<bool> ("network_keepalive", network_keepalive_logging_value);
toml.get<bool> ("network_node_id_handshake", network_node_id_handshake_logging_value);
toml.get<bool> ("network_telemetry_logging", network_telemetry_logging_value);
toml.get<bool> ("network_rejected_logging", network_rejected_logging_value);
toml.get<bool> ("node_lifetime_tracing", node_lifetime_tracing_value);
toml.get<bool> ("insufficient_work", insufficient_work_logging_value);
toml.get<bool> ("log_ipc", log_ipc_value);
toml.get<bool> ("bulk_pull", bulk_pull_logging_value);
toml.get<bool> ("work_generation_time", work_generation_time_value);
toml.get<bool> ("upnp_details", upnp_details_logging_value);
toml.get<bool> ("timing", timing_logging_value);
toml.get<bool> ("active_update", active_update_value);
toml.get<bool> ("election_result", election_result_logging_value);
toml.get<bool> ("log_to_cerr", log_to_cerr_value);
toml.get<bool> ("flush", flush);
toml.get<bool> ("single_line_record", single_line_record_value);
toml.get<uintmax_t> ("max_size", max_size);
toml.get<uintmax_t> ("rotation_size", rotation_size);
auto min_time_between_log_output_l = min_time_between_log_output.count ();
toml.get ("min_time_between_output", min_time_between_log_output_l);
min_time_between_log_output = std::chrono::milliseconds (min_time_between_log_output_l);
toml.get ("stable_log_filename", stable_log_filename);
return toml.get_error ();
}
bool nano::logging::ledger_logging () const
{
return ledger_logging_value;
}
bool nano::logging::ledger_duplicate_logging () const
{
return ledger_logging () && ledger_duplicate_logging_value;
}
bool nano::logging::ledger_rollback_logging () const
{
return ledger_rollback_logging_value;
}
bool nano::logging::vote_logging () const
{
return vote_logging_value;
}
bool nano::logging::rep_crawler_logging () const
{
return rep_crawler_logging_value;
}
bool nano::logging::election_expiration_tally_logging () const
{
return election_expiration_tally_logging_value;
}
bool nano::logging::election_fork_tally_logging () const
{
return election_fork_tally_logging_value;
}
bool nano::logging::network_logging () const
{
return network_logging_value;
}
bool nano::logging::network_timeout_logging () const
{
return network_logging () && network_timeout_logging_value;
}
bool nano::logging::network_message_logging () const
{
return network_logging () && network_message_logging_value;
}
bool nano::logging::network_publish_logging () const
{
return network_logging () && network_publish_logging_value;
}
bool nano::logging::network_packet_logging () const
{
return network_logging () && network_packet_logging_value;
}
bool nano::logging::network_keepalive_logging () const
{
return network_logging () && network_keepalive_logging_value;
}
bool nano::logging::network_node_id_handshake_logging () const
{
return network_logging () && network_node_id_handshake_logging_value;
}
bool nano::logging::network_telemetry_logging () const
{
return network_logging () && network_telemetry_logging_value;
}
bool nano::logging::network_rejected_logging () const
{
return network_logging () && network_rejected_logging_value;
}
bool nano::logging::node_lifetime_tracing () const
{
return node_lifetime_tracing_value;
}
bool nano::logging::insufficient_work_logging () const
{
return network_logging () && insufficient_work_logging_value;
}
bool nano::logging::log_ipc () const
{
return network_logging () && log_ipc_value;
}
bool nano::logging::bulk_pull_logging () const
{
return network_logging () && bulk_pull_logging_value;
}
bool nano::logging::callback_logging () const
{
return network_logging ();
}
bool nano::logging::work_generation_time () const
{
return work_generation_time_value;
}
bool nano::logging::upnp_details_logging () const
{
return upnp_details_logging_value;
}
bool nano::logging::timing_logging () const
{
return timing_logging_value;
}
bool nano::logging::active_update_logging () const
{
return active_update_value;
}
bool nano::logging::election_result_logging () const
{
return election_result_logging_value;
}
bool nano::logging::log_to_cerr () const
{
return log_to_cerr_value;
}
bool nano::logging::single_line_record () const
{
return single_line_record_value;
}

View file

@ -1,105 +0,0 @@
#pragma once
#include <nano/lib/errors.hpp>
#include <boost/log/detail/config.hpp>
#include <boost/shared_ptr.hpp>
#include <atomic>
#include <chrono>
#include <cstdint>
#define FATAL_LOG_PREFIX "FATAL ERROR: "
namespace boost
{
BOOST_LOG_OPEN_NAMESPACE
namespace sinks
{
class text_file_backend;
template <class SinkBackendT>
class synchronous_sink;
}
BOOST_LOG_CLOSE_NAMESPACE
}
namespace nano
{
class tomlconfig;
class logging final
{
public:
nano::error serialize_toml (nano::tomlconfig &) const;
nano::error deserialize_toml (nano::tomlconfig &);
bool ledger_logging () const;
bool ledger_duplicate_logging () const;
bool ledger_rollback_logging () const;
bool vote_logging () const;
bool rep_crawler_logging () const;
bool election_fork_tally_logging () const;
bool election_expiration_tally_logging () const;
bool network_logging () const;
bool network_timeout_logging () const;
bool network_message_logging () const;
bool network_publish_logging () const;
bool network_packet_logging () const;
bool network_keepalive_logging () const;
bool network_node_id_handshake_logging () const;
bool network_telemetry_logging () const;
bool network_rejected_logging () const;
bool node_lifetime_tracing () const;
bool insufficient_work_logging () const;
bool upnp_details_logging () const;
bool timing_logging () const;
bool log_ipc () const;
bool bulk_pull_logging () const;
bool callback_logging () const;
bool work_generation_time () const;
bool active_update_logging () const;
bool election_result_logging () const;
bool log_to_cerr () const;
bool single_line_record () const;
void init (std::filesystem::path const &);
bool ledger_logging_value{ false };
bool ledger_duplicate_logging_value{ false };
bool ledger_rollback_logging_value{ false };
bool vote_logging_value{ false };
bool rep_crawler_logging_value{ false };
bool election_fork_tally_logging_value{ false };
bool election_expiration_tally_logging_value{ false };
bool network_logging_value{ true };
bool network_timeout_logging_value{ false };
bool network_message_logging_value{ false };
bool network_publish_logging_value{ false };
bool network_packet_logging_value{ false };
bool network_keepalive_logging_value{ false };
bool network_node_id_handshake_logging_value{ false };
bool network_telemetry_logging_value{ false };
bool network_rejected_logging_value{ false };
bool node_lifetime_tracing_value{ false };
bool insufficient_work_logging_value{ true };
bool log_ipc_value{ true };
bool bulk_pull_logging_value{ false };
bool work_generation_time_value{ true };
bool upnp_details_logging_value{ false };
bool timing_logging_value{ false };
bool active_update_value{ false };
bool election_result_logging_value{ false };
bool log_to_cerr_value{ false };
bool flush{ true };
uintmax_t max_size{ 128 * 1024 * 1024 };
uintmax_t rotation_size{ 4 * 1024 * 1024 };
bool stable_log_filename{ false };
std::chrono::milliseconds min_time_between_log_output{ 5 };
bool single_line_record_value{ false };
static void release_file_sink ();
private:
static boost::shared_ptr<boost::log::sinks::synchronous_sink<boost::log::sinks::text_file_backend>> file_sink;
static std::atomic_flag logging_already_added;
};
}

View file

@ -2,7 +2,7 @@
#include <nano/store/lmdb/lmdb.hpp>
#include <nano/store/rocksdb/rocksdb.hpp>
std::unique_ptr<nano::store::component> nano::make_store (nano::logger_mt & logger, std::filesystem::path const & path, nano::ledger_constants & constants, bool read_only, bool add_db_postfix, nano::rocksdb_config const & rocksdb_config, nano::txn_tracking_config const & txn_tracking_config_a, std::chrono::milliseconds block_processor_batch_max_time_a, nano::lmdb_config const & lmdb_config_a, bool backup_before_upgrade)
std::unique_ptr<nano::store::component> nano::make_store (nano::logger & logger, std::filesystem::path const & path, nano::ledger_constants & constants, bool read_only, bool add_db_postfix, nano::rocksdb_config const & rocksdb_config, nano::txn_tracking_config const & txn_tracking_config_a, std::chrono::milliseconds block_processor_batch_max_time_a, nano::lmdb_config const & lmdb_config_a, bool backup_before_upgrade)
{
if (rocksdb_config.enable)
{

View file

@ -2,7 +2,7 @@
#include <nano/lib/diagnosticsconfig.hpp>
#include <nano/lib/lmdbconfig.hpp>
#include <nano/lib/logger_mt.hpp>
#include <nano/lib/logging.hpp>
#include <nano/lib/rocksdbconfig.hpp>
#include <chrono>
@ -22,5 +22,5 @@ class component;
namespace nano
{
std::unique_ptr<nano::store::component> make_store (nano::logger_mt & logger, std::filesystem::path const & path, nano::ledger_constants & constants, bool open_read_only = false, bool add_db_postfix = true, nano::rocksdb_config const & rocksdb_config = nano::rocksdb_config{}, nano::txn_tracking_config const & txn_tracking_config_a = nano::txn_tracking_config{}, std::chrono::milliseconds block_processor_batch_max_time_a = std::chrono::milliseconds (5000), nano::lmdb_config const & lmdb_config_a = nano::lmdb_config{}, bool backup_before_upgrade = false);
std::unique_ptr<nano::store::component> make_store (nano::logger &, std::filesystem::path const & path, nano::ledger_constants & constants, bool open_read_only = false, bool add_db_postfix = true, nano::rocksdb_config const & rocksdb_config = nano::rocksdb_config{}, nano::txn_tracking_config const & txn_tracking_config_a = nano::txn_tracking_config{}, std::chrono::milliseconds block_processor_batch_max_time_a = std::chrono::milliseconds (5000), nano::lmdb_config const & lmdb_config_a = nano::lmdb_config{}, bool backup_before_upgrade = false);
}

View file

@ -82,86 +82,6 @@ bool nano::message_header::deserialize (nano::stream & stream_a)
return error;
}
std::string nano::to_string (nano::message_type type)
{
switch (type)
{
case nano::message_type::invalid:
return "invalid";
case nano::message_type::not_a_type:
return "not_a_type";
case nano::message_type::keepalive:
return "keepalive";
case nano::message_type::publish:
return "publish";
case nano::message_type::confirm_req:
return "confirm_req";
case nano::message_type::confirm_ack:
return "confirm_ack";
case nano::message_type::bulk_pull:
return "bulk_pull";
case nano::message_type::bulk_push:
return "bulk_push";
case nano::message_type::frontier_req:
return "frontier_req";
case nano::message_type::node_id_handshake:
return "node_id_handshake";
case nano::message_type::bulk_pull_account:
return "bulk_pull_account";
case nano::message_type::telemetry_req:
return "telemetry_req";
case nano::message_type::telemetry_ack:
return "telemetry_ack";
case nano::message_type::asc_pull_req:
return "asc_pull_req";
case nano::message_type::asc_pull_ack:
return "asc_pull_ack";
// default case intentionally omitted to cause warnings for unhandled enums
}
return "n/a";
}
nano::stat::detail nano::to_stat_detail (nano::message_type type)
{
switch (type)
{
case nano::message_type::invalid:
return nano::stat::detail::invalid;
case nano::message_type::not_a_type:
return nano::stat::detail::not_a_type;
case nano::message_type::keepalive:
return nano::stat::detail::keepalive;
case nano::message_type::publish:
return nano::stat::detail::publish;
case nano::message_type::confirm_req:
return nano::stat::detail::confirm_req;
case nano::message_type::confirm_ack:
return nano::stat::detail::confirm_ack;
case nano::message_type::bulk_pull:
return nano::stat::detail::bulk_pull;
case nano::message_type::bulk_push:
return nano::stat::detail::bulk_push;
case nano::message_type::frontier_req:
return nano::stat::detail::frontier_req;
case nano::message_type::node_id_handshake:
return nano::stat::detail::node_id_handshake;
case nano::message_type::bulk_pull_account:
return nano::stat::detail::bulk_pull_account;
case nano::message_type::telemetry_req:
return nano::stat::detail::telemetry_req;
case nano::message_type::telemetry_ack:
return nano::stat::detail::telemetry_ack;
case nano::message_type::asc_pull_req:
return nano::stat::detail::asc_pull_req;
case nano::message_type::asc_pull_ack:
return nano::stat::detail::asc_pull_ack;
// default case intentionally omitted to cause warnings for unhandled enums
}
debug_assert (false);
return {};
}
std::string nano::message_header::to_string () const
{
// Cast to uint16_t to get integer value since uint8_t is treated as an unsigned char in string formatting.
@ -169,11 +89,11 @@ std::string nano::message_header::to_string () const
uint16_t version_max_l = static_cast<uint16_t> (version_max);
uint16_t version_using_l = static_cast<uint16_t> (version_using);
uint16_t version_min_l = static_cast<uint16_t> (version_min);
std::string type_text = nano::to_string (type);
auto type_text = nano::to_string (type);
std::stringstream stream;
stream << boost::format ("NetID: %1%(%2%), ") % nano::to_string_hex (static_cast<uint16_t> (network)) % nano::network::to_string (network);
stream << boost::format ("NetID: %1%(%2%), ") % nano::to_string_hex (static_cast<uint16_t> (network)) % nano::to_string (network);
stream << boost::format ("VerMaxUsingMin: %1%/%2%/%3%, ") % version_max_l % version_using_l % version_min_l;
stream << boost::format ("MsgType: %1%(%2%), ") % type_l % type_text;
stream << boost::format ("Extensions: %1%") % nano::to_string_hex (static_cast<uint16_t> (extensions.to_ulong ()));
@ -2068,3 +1988,87 @@ void nano::asc_pull_ack::frontiers_payload::deserialize (nano::stream & stream)
current = deserialize_frontier (stream);
}
}
/*
*
*/
std::string_view nano::to_string (nano::message_type type)
{
switch (type)
{
case nano::message_type::invalid:
return "invalid";
case nano::message_type::not_a_type:
return "not_a_type";
case nano::message_type::keepalive:
return "keepalive";
case nano::message_type::publish:
return "publish";
case nano::message_type::confirm_req:
return "confirm_req";
case nano::message_type::confirm_ack:
return "confirm_ack";
case nano::message_type::bulk_pull:
return "bulk_pull";
case nano::message_type::bulk_push:
return "bulk_push";
case nano::message_type::frontier_req:
return "frontier_req";
case nano::message_type::node_id_handshake:
return "node_id_handshake";
case nano::message_type::bulk_pull_account:
return "bulk_pull_account";
case nano::message_type::telemetry_req:
return "telemetry_req";
case nano::message_type::telemetry_ack:
return "telemetry_ack";
case nano::message_type::asc_pull_req:
return "asc_pull_req";
case nano::message_type::asc_pull_ack:
return "asc_pull_ack";
// default case intentionally omitted to cause warnings for unhandled enums
}
return "n/a";
}
nano::stat::detail nano::to_stat_detail (nano::message_type type)
{
switch (type)
{
case nano::message_type::invalid:
return nano::stat::detail::invalid;
case nano::message_type::not_a_type:
return nano::stat::detail::not_a_type;
case nano::message_type::keepalive:
return nano::stat::detail::keepalive;
case nano::message_type::publish:
return nano::stat::detail::publish;
case nano::message_type::confirm_req:
return nano::stat::detail::confirm_req;
case nano::message_type::confirm_ack:
return nano::stat::detail::confirm_ack;
case nano::message_type::bulk_pull:
return nano::stat::detail::bulk_pull;
case nano::message_type::bulk_push:
return nano::stat::detail::bulk_push;
case nano::message_type::frontier_req:
return nano::stat::detail::frontier_req;
case nano::message_type::node_id_handshake:
return nano::stat::detail::node_id_handshake;
case nano::message_type::bulk_pull_account:
return nano::stat::detail::bulk_pull_account;
case nano::message_type::telemetry_req:
return nano::stat::detail::telemetry_req;
case nano::message_type::telemetry_ack:
return nano::stat::detail::telemetry_ack;
case nano::message_type::asc_pull_req:
return nano::stat::detail::asc_pull_req;
case nano::message_type::asc_pull_ack:
return nano::stat::detail::asc_pull_ack;
// default case intentionally omitted to cause warnings for unhandled enums
}
debug_assert (false);
return {};
}

View file

@ -44,8 +44,8 @@ enum class message_type : uint8_t
asc_pull_ack = 0x0f,
};
std::string to_string (message_type);
stat::detail to_stat_detail (message_type);
std::string_view to_string (nano::message_type);
stat::detail to_stat_detail (nano::message_type);
enum class bulk_pull_account_flags : uint8_t
{

View file

@ -1,5 +1,6 @@
#include <nano/crypto_lib/random_pool_shuffle.hpp>
#include <nano/lib/threading.hpp>
#include <nano/lib/utility.hpp>
#include <nano/node/bootstrap_ascending/service.hpp>
#include <nano/node/network.hpp>
#include <nano/node/node.hpp>
@ -27,10 +28,9 @@ nano::network::network (nano::node & node_a, uint16_t port_a) :
port (port_a),
disconnect_observer ([] () {})
{
// TCP
for (std::size_t i = 0; i < node.config.network_threads && !node.flags.disable_tcp_realtime; ++i)
{
packet_processing_threads.emplace_back (nano::thread_attributes::get_default (), [this] () {
packet_processing_threads.emplace_back (nano::thread_attributes::get_default (), [this, i] () {
nano::thread_role::set (nano::thread_role::name::packet_processing);
try
{
@ -38,28 +38,24 @@ nano::network::network (nano::node & node_a, uint16_t port_a) :
}
catch (boost::system::error_code & ec)
{
this->node.logger.always_log (FATAL_LOG_PREFIX, ec.message ());
node.logger.critical (nano::log::type::network, "Error: {}", ec.message ());
release_assert (false);
}
catch (std::error_code & ec)
{
this->node.logger.always_log (FATAL_LOG_PREFIX, ec.message ());
node.logger.critical (nano::log::type::network, "Error: {}", ec.message ());
release_assert (false);
}
catch (std::runtime_error & err)
{
this->node.logger.always_log (FATAL_LOG_PREFIX, err.what ());
node.logger.critical (nano::log::type::network, "Error: {}", err.what ());
release_assert (false);
}
catch (...)
{
this->node.logger.always_log (FATAL_LOG_PREFIX, "Unknown exception");
node.logger.critical (nano::log::type::network, "Unknown error");
release_assert (false);
}
if (this->node.config.logging.network_packet_logging ())
{
this->node.logger.try_log ("Exiting TCP packet processing thread");
}
});
}
}
@ -131,10 +127,11 @@ void nano::network::send_node_id_handshake (std::shared_ptr<nano::transport::cha
nano::node_id_handshake message{ node.network_params.network, query, response };
if (node.config.logging.network_node_id_handshake_logging ())
{
node.logger.try_log (boost::str (boost::format ("Node ID handshake sent with node ID %1% to %2%: query %3%, respond_to %4% (signature %5%)") % node.node_id.pub.to_node_id () % channel_a->get_endpoint () % (query ? query->cookie.to_string () : std::string ("[none]")) % (respond_to ? respond_to->to_string () : std::string ("[none]")) % (response ? response->signature.to_string () : std::string ("[none]"))));
}
node.logger.debug (nano::log::type::network, "Node ID handshake sent to: {} (query: {}, respond to: {}, signature: {})",
nano::util::to_str (channel_a->get_endpoint ()),
(query ? query->cookie.to_string () : "<none>"),
(respond_to ? respond_to->to_string () : "<none>"),
(response ? response->signature.to_string () : "<none>"));
channel_a->send (message);
}
@ -260,10 +257,6 @@ void nano::network::broadcast_confirm_req (std::shared_ptr<nano::block> const &
void nano::network::broadcast_confirm_req_base (std::shared_ptr<nano::block> const & block_a, std::shared_ptr<std::vector<std::shared_ptr<nano::transport::channel>>> const & endpoints_a, unsigned delay_a, bool resumption)
{
std::size_t const max_reps = 10;
if (!resumption && node.config.logging.network_logging ())
{
node.logger.try_log (boost::str (boost::format ("Broadcasting confirm req for block %1% to %2% representatives") % block_a->hash ().to_string () % endpoints_a->size ()));
}
auto count (0);
while (!endpoints_a->empty () && count < max_reps)
{
@ -288,11 +281,6 @@ void nano::network::broadcast_confirm_req_base (std::shared_ptr<nano::block> con
void nano::network::broadcast_confirm_req_batched_many (std::unordered_map<std::shared_ptr<nano::transport::channel>, std::deque<std::pair<nano::block_hash, nano::root>>> request_bundle_a, std::function<void ()> callback_a, unsigned delay_a, bool resumption_a)
{
if (!resumption_a && node.config.logging.network_logging ())
{
node.logger.try_log (boost::str (boost::format ("Broadcasting batch confirm req to %1% representatives") % request_bundle_a.size ()));
}
for (auto i (request_bundle_a.begin ()), n (request_bundle_a.end ()); i != n;)
{
std::vector<std::pair<nano::block_hash, nano::root>> roots_hashes_l;
@ -365,18 +353,13 @@ class network_message_visitor : public nano::message_visitor
{
public:
network_message_visitor (nano::node & node_a, std::shared_ptr<nano::transport::channel> const & channel_a) :
node (node_a),
channel (channel_a)
node{ node_a },
channel{ channel_a }
{
}
void keepalive (nano::keepalive const & message_a) override
{
if (node.config.logging.network_keepalive_logging ())
{
node.logger.try_log (boost::str (boost::format ("Received keepalive message from %1%") % channel->to_string ()));
}
node.network.merge_peers (message_a.peers);
// Check for special node port data
@ -393,11 +376,6 @@ public:
void publish (nano::publish const & message_a) override
{
if (node.config.logging.network_message_logging ())
{
node.logger.try_log (boost::str (boost::format ("Publish message from %1% for %2%") % channel->to_string () % message_a.block->hash ().to_string ()));
}
if (!node.block_processor.full ())
{
node.process_active (message_a.block);
@ -411,14 +389,6 @@ public:
void confirm_req (nano::confirm_req const & message_a) override
{
if (node.config.logging.network_message_logging ())
{
if (!message_a.roots_hashes.empty ())
{
node.logger.try_log (boost::str (boost::format ("Confirm_req message from %1% for hashes:roots %2%") % channel->to_string () % message_a.roots_string ()));
}
}
// Don't load nodes with disabled voting
if (node.config.enable_voting && node.wallets.reps ().voting > 0)
{
@ -431,11 +401,6 @@ public:
void confirm_ack (nano::confirm_ack const & message_a) override
{
if (node.config.logging.network_message_logging ())
{
node.logger.try_log (boost::str (boost::format ("Received confirm_ack message from %1% for %2% timestamp %3%") % channel->to_string () % message_a.vote->hashes_string () % std::to_string (message_a.vote->timestamp ())));
}
if (!message_a.vote->account.is_zero ())
{
node.vote_processor.vote (message_a.vote, channel);
@ -469,11 +434,6 @@ public:
void telemetry_req (nano::telemetry_req const & message_a) override
{
if (node.config.logging.network_telemetry_logging ())
{
node.logger.try_log (boost::str (boost::format ("Telemetry_req message from %1%") % channel->to_string ()));
}
// Send an empty telemetry_ack if we do not want, just to acknowledge that we have received the message to
// remove any timeouts on the server side waiting for a message.
nano::telemetry_ack telemetry_ack{ node.network_params.network };
@ -487,11 +447,6 @@ public:
void telemetry_ack (nano::telemetry_ack const & message_a) override
{
if (node.config.logging.network_telemetry_logging ())
{
node.logger.try_log (boost::str (boost::format ("Received telemetry_ack message from %1%") % channel->to_string ()));
}
node.telemetry.process (message_a, channel);
}
@ -515,7 +470,7 @@ void nano::network::process_message (nano::message const & message, std::shared_
{
node.stats.inc (nano::stat::type::message, nano::to_stat_detail (message.header.type), nano::stat::dir::in);
network_message_visitor visitor (node, channel);
network_message_visitor visitor{ node, channel };
message.visit (visitor);
}
@ -998,23 +953,3 @@ std::unique_ptr<nano::container_info_component> nano::syn_cookies::collect_conta
composite->add_component (std::make_unique<container_info_leaf> (container_info{ "syn_cookies_per_ip", syn_cookies_per_ip_count, sizeof (decltype (cookies_per_ip)::value_type) }));
return composite;
}
std::string nano::network::to_string (nano::networks network)
{
switch (network)
{
case nano::networks::invalid:
return "invalid";
case nano::networks::nano_beta_network:
return "beta";
case nano::networks::nano_dev_network:
return "dev";
case nano::networks::nano_live_network:
return "live";
case nano::networks::nano_test_network:
return "test";
// default case intentionally omitted to cause warnings for unhandled enums
}
return "n/a";
}

View file

@ -1,5 +1,6 @@
#pragma once
#include <nano/lib/logging.hpp>
#include <nano/node/common.hpp>
#include <nano/node/peer_exclusion.hpp>
#include <nano/node/transport/tcp.hpp>
@ -133,8 +134,6 @@ public:
std::optional<nano::node_id_handshake::query_payload> prepare_handshake_query (nano::endpoint const & remote_endpoint);
nano::node_id_handshake::response_payload prepare_handshake_response (nano::node_id_handshake::query_payload const & query, bool v2) const;
static std::string to_string (nano::networks);
private:
void process_message (nano::message const &, std::shared_ptr<nano::transport::channel> const &);
@ -158,5 +157,6 @@ public:
static std::size_t const confirm_req_hashes_max = 7;
static std::size_t const confirm_ack_hashes_max = 12;
};
std::unique_ptr<container_info_component> collect_container_info (network & network, std::string const & name);
}

View file

@ -84,7 +84,7 @@ void nano::node::keepalive (std::string const & address_a, uint16_t port_a)
}
else
{
node_l->logger.try_log (boost::str (boost::format ("Error resolving address: %1%:%2%: %3%") % address_a % port_a % ec.message ()));
node_l->logger.error (nano::log::type::node, "Error resolving address for keepalive: {}:{} ({})", address_a, port_a, ec.message ());
}
});
}
@ -103,13 +103,14 @@ std::unique_ptr<nano::container_info_component> nano::collect_container_info (re
return composite;
}
nano::keypair nano::load_or_create_node_id (std::filesystem::path const & application_path, nano::logger_mt & logger)
nano::keypair nano::load_or_create_node_id (std::filesystem::path const & application_path)
{
auto node_private_key_path = application_path / "node_id_private.key";
std::ifstream ifs (node_private_key_path.c_str ());
if (ifs.good ())
{
logger.always_log (boost::str (boost::format ("%1% exists, reading node id from it") % node_private_key_path.string ()));
nano::default_logger ().info (nano::log::type::init, "Reading node id from: '{}'", node_private_key_path.string ());
std::string node_private_key;
ifs >> node_private_key;
release_assert (node_private_key.size () == 64);
@ -119,7 +120,8 @@ nano::keypair nano::load_or_create_node_id (std::filesystem::path const & applic
else
{
// no node_id found, generate new one
logger.always_log (boost::str (boost::format ("%1% does not exist, creating a new node_id") % node_private_key_path.string ()));
nano::default_logger ().info (nano::log::type::init, "Generating a new node id, saving to: '{}'", node_private_key_path.string ());
nano::keypair kp;
std::ofstream ofs (node_private_key_path.c_str (), std::ofstream::out | std::ofstream::trunc);
ofs << kp.prv.to_string () << std::endl
@ -130,24 +132,25 @@ nano::keypair nano::load_or_create_node_id (std::filesystem::path const & applic
}
}
nano::node::node (boost::asio::io_context & io_ctx_a, uint16_t peering_port_a, std::filesystem::path const & application_path_a, nano::logging const & logging_a, nano::work_pool & work_a, nano::node_flags flags_a, unsigned seq) :
node (io_ctx_a, application_path_a, nano::node_config (peering_port_a, logging_a), work_a, flags_a, seq)
nano::node::node (boost::asio::io_context & io_ctx_a, uint16_t peering_port_a, std::filesystem::path const & application_path_a, nano::work_pool & work_a, nano::node_flags flags_a, unsigned seq) :
node (io_ctx_a, application_path_a, nano::node_config (peering_port_a), work_a, flags_a, seq)
{
}
nano::node::node (boost::asio::io_context & io_ctx_a, std::filesystem::path const & application_path_a, nano::node_config const & config_a, nano::work_pool & work_a, nano::node_flags flags_a, unsigned seq) :
node_id{ load_or_create_node_id (application_path_a) },
write_database_queue (!flags_a.force_use_write_database_queue && (config_a.rocksdb_config.enable)),
io_ctx (io_ctx_a),
node_initialized_latch (1),
config (config_a),
network_params{ config.network_params },
logger{ make_logger_identifier (node_id) },
stats (config.stats_config),
workers{ config.background_threads, nano::thread_role::name::worker },
bootstrap_workers{ config.bootstrap_serving_threads, nano::thread_role::name::bootstrap_worker },
flags (flags_a),
work (work_a),
distributed_work (*this),
logger (config_a.logging.min_time_between_log_output),
store_impl (nano::make_store (logger, application_path_a, network_params.ledger, flags.read_only, true, config_a.rocksdb_config, config_a.diagnostics_config.txn_tracking, config_a.block_processor_batch_max_time, config_a.lmdb_config, config_a.backup_before_upgrade)),
store (*store_impl),
unchecked{ stats, flags.disable_block_processor_unchecked_deletion },
@ -180,7 +183,7 @@ nano::node::node (boost::asio::io_context & io_ctx_a, std::filesystem::path cons
online_reps (ledger, config),
history{ config.network_params.voting },
vote_uniquer{},
confirmation_height_processor (ledger, write_database_queue, config.conf_height_processor_batch_min_time, config.logging, logger, node_initialized_latch, flags.confirmation_height_processor_mode),
confirmation_height_processor (ledger, write_database_queue, config.conf_height_processor_batch_min_time, logger, node_initialized_latch, flags.confirmation_height_processor_mode),
vote_cache{ config.vote_cache, stats },
generator{ config, ledger, wallets, vote_processor, history, network, stats, /* non-final */ false },
final_generator{ config, ledger, wallets, vote_processor, history, network, stats, /* final */ true },
@ -200,6 +203,8 @@ nano::node::node (boost::asio::io_context & io_ctx_a, std::filesystem::path cons
gap_tracker{ gap_cache },
process_live_dispatcher{ ledger, scheduler.priority, vote_cache, websocket }
{
logger.debug (nano::log::type::node, "Constructing node...");
block_broadcast.connect (block_processor);
block_publisher.connect (block_processor);
gap_tracker.connect (block_processor);
@ -288,10 +293,7 @@ nano::node::node (boost::asio::io_context & io_ctx_a, std::filesystem::path cons
}
else
{
if (node_l->config.logging.callback_logging ())
{
node_l->logger.always_log (boost::str (boost::format ("Error resolving callback: %1%:%2%: %3%") % address % port % ec.message ()));
}
node_l->logger.error (nano::log::type::rpc_callbacks, "Error resolving callback: {}:{} ({})", address, port, ec.message ());
node_l->stats.inc (nano::stat::type::error, nano::stat::detail::http_callback, nano::stat::dir::out);
}
});
@ -338,26 +340,25 @@ nano::node::node (boost::asio::io_context & io_ctx_a, std::filesystem::path cons
this->distributed_work.cancel (root_a);
});
logger.always_log ("Node starting, version: ", NANO_VERSION_STRING);
logger.always_log ("Build information: ", BUILD_INFO);
logger.always_log ("Database backend: ", store.vendor_get ());
auto const network_label = network_params.network.get_current_network_as_string ();
logger.always_log ("Active network: ", network_label);
logger.always_log (boost::str (boost::format ("Work pool running %1% threads %2%") % work.threads.size () % (work.opencl ? "(1 for OpenCL)" : "")));
logger.always_log (boost::str (boost::format ("%1% work peers configured") % config.work_peers.size ()));
logger.info (nano::log::type::node, "Node starting, version: {}", NANO_VERSION_STRING);
logger.info (nano::log::type::node, "Build information: {}", BUILD_INFO);
logger.info (nano::log::type::node, "Active network: {}", network_label);
logger.info (nano::log::type::node, "Database backend: {}", store.vendor_get ());
logger.info (nano::log::type::node, "Data path: {}", application_path.string ());
logger.info (nano::log::type::node, "Work pool threads: {} ({})", work.threads.size (), (work.opencl ? "OpenCL" : "CPU"));
logger.info (nano::log::type::node, "Work peers: {}", config.work_peers.size ());
logger.info (nano::log::type::node, "Node ID: {}", node_id.pub.to_node_id ());
if (!work_generation_enabled ())
{
logger.always_log ("Work generation is disabled");
logger.info (nano::log::type::node, "Work generation is disabled");
}
if (config.logging.node_lifetime_tracing ())
{
logger.always_log ("Constructing node");
}
logger.always_log (boost::str (boost::format ("Outbound Voting Bandwidth limited to %1% bytes per second, burst ratio %2%") % config.bandwidth_limit % config.bandwidth_limit_burst_ratio));
logger.info (nano::log::type::node, "Outbound bandwidth limit: {} bytes/s, burst ratio: {}",
config.bandwidth_limit,
config.bandwidth_limit_burst_ratio);
// First do a pass with a read to see if any writing needs doing, this saves needing to open a write lock (and potentially blocking)
auto is_initialized (false);
@ -375,59 +376,69 @@ nano::node::node (boost::asio::io_context & io_ctx_a, std::filesystem::path cons
if (!ledger.block_or_pruned_exists (config.network_params.ledger.genesis->hash ()))
{
std::stringstream ss;
ss << "Genesis block not found. This commonly indicates a configuration issue, check that the --network or --data_path command line arguments are correct, "
"and also the ledger backend node config option. If using a read-only CLI command a ledger must already exist, start the node with --daemon first.";
logger.critical (nano::log::type::node, "Genesis block not found. This commonly indicates a configuration issue, check that the --network or --data_path command line arguments are correct, and also the ledger backend node config option. If using a read-only CLI command a ledger must already exist, start the node with --daemon first.");
if (network_params.network.is_beta_network ())
{
ss << " Beta network may have reset, try clearing database files";
logger.critical (nano::log::type::node, "Beta network may have reset, try clearing database files");
}
auto const str = ss.str ();
logger.always_log (str);
std::cerr << str << std::endl;
std::exit (1);
}
if (config.enable_voting)
{
std::ostringstream stream;
stream << "Voting is enabled, more system resources will be used";
auto voting (wallets.reps ().voting);
if (voting > 0)
auto reps = wallets.reps ();
logger.info (nano::log::type::node, "Voting is enabled, more system resources will be used, local representatives: {}", reps.accounts.size ());
for (auto const & account : reps.accounts)
{
stream << ". " << voting << " representative(s) are configured";
if (voting > 1)
{
stream << ". Voting with more than one representative can limit performance";
}
logger.info (nano::log::type::node, "Local representative: {}", account.to_account ());
}
if (reps.accounts.size () > 1)
{
logger.warn (nano::log::type::node, "Voting with more than one representative can limit performance");
}
logger.always_log (stream.str ());
}
node_id = nano::load_or_create_node_id (application_path, logger);
logger.always_log ("Node ID: ", node_id.pub.to_node_id ());
if ((network_params.network.is_live_network () || network_params.network.is_beta_network ()) && !flags.inactive_node)
{
auto const bootstrap_weights = get_bootstrap_weights ();
ledger.bootstrap_weight_max_blocks = bootstrap_weights.first;
logger.info (nano::log::type::node, "Initial bootstrap height: {}", ledger.bootstrap_weight_max_blocks);
logger.info (nano::log::type::node, "Current ledger height: {}", ledger.cache.block_count.load ());
// Use bootstrap weights if initial bootstrap is not completed
const bool use_bootstrap_weight = ledger.cache.block_count < bootstrap_weights.first;
if (use_bootstrap_weight)
{
logger.info (nano::log::type::node, "Using predefined representative weights, since block count is less than bootstrap threshold");
ledger.bootstrap_weights = bootstrap_weights.second;
for (auto const & rep : ledger.bootstrap_weights)
logger.info (nano::log::type::node, "************************************ Bootstrap weights ************************************");
// Sort the weights
std::vector<std::pair<nano::account, nano::uint128_t>> sorted_weights (ledger.bootstrap_weights.begin (), ledger.bootstrap_weights.end ());
std::sort (sorted_weights.begin (), sorted_weights.end (), [] (auto const & entry1, auto const & entry2) {
return entry1.second > entry2.second;
});
for (auto const & rep : sorted_weights)
{
logger.always_log ("Using bootstrap rep weight: ", rep.first.to_account (), " -> ", nano::uint128_union (rep.second).format_balance (Mxrb_ratio, 0, true), " XRB");
logger.info (nano::log::type::node, "Using bootstrap rep weight: {} -> {}",
rep.first.to_account (),
nano::uint128_union (rep.second).format_balance (Mxrb_ratio, 0, true));
}
logger.info (nano::log::type::node, "************************************ ================= ************************************");
}
ledger.bootstrap_weight_max_blocks = bootstrap_weights.first;
// Drop unchecked blocks if initial bootstrap is completed
if (!flags.disable_unchecked_drop && !use_bootstrap_weight && !flags.read_only)
{
logger.info (nano::log::type::node, "Dropping unchecked blocks...");
unchecked.clear ();
logger.always_log ("Dropping unchecked blocks");
}
}
@ -437,16 +448,12 @@ nano::node::node (boost::asio::io_context & io_ctx_a, std::filesystem::path cons
{
if (config.enable_voting && !flags.inactive_node)
{
std::string str = "Incompatibility detected between config node.enable_voting and existing pruned blocks";
logger.always_log (str);
std::cerr << str << std::endl;
logger.critical (nano::log::type::node, "Incompatibility detected between config node.enable_voting and existing pruned blocks");
std::exit (1);
}
else if (!flags.enable_pruning && !flags.inactive_node)
{
std::string str = "To start node with existing pruned blocks use launch flag --enable_pruning";
logger.always_log (str);
std::cerr << str << std::endl;
logger.critical (nano::log::type::node, "To start node with existing pruned blocks use launch flag --enable_pruning");
std::exit (1);
}
}
@ -456,13 +463,11 @@ nano::node::node (boost::asio::io_context & io_ctx_a, std::filesystem::path cons
nano::node::~node ()
{
if (config.logging.node_lifetime_tracing ())
{
logger.always_log ("Destructing node");
}
logger.debug (nano::log::type::node, "Destructing node...");
stop ();
}
// TODO: Move to a separate class
void nano::node::do_rpc_callback (boost::asio::ip::tcp::resolver::iterator i_a, std::string const & address, uint16_t port, std::shared_ptr<std::string> const & target, std::shared_ptr<std::string> const & body, std::shared_ptr<boost::asio::ip::tcp::resolver> const & resolver)
{
if (i_a != boost::asio::ip::tcp::resolver::iterator{})
@ -494,41 +499,30 @@ void nano::node::do_rpc_callback (boost::asio::ip::tcp::resolver::iterator i_a,
}
else
{
if (node_l->config.logging.callback_logging ())
{
node_l->logger.try_log (boost::str (boost::format ("Callback to %1%:%2% failed with status: %3%") % address % port % resp->result ()));
}
node_l->logger.error (nano::log::type::rpc_callbacks, "Callback to {}:{} failed [status: {}]", address, port, nano::util::to_str (resp->result ()));
node_l->stats.inc (nano::stat::type::error, nano::stat::detail::http_callback, nano::stat::dir::out);
}
}
else
{
if (node_l->config.logging.callback_logging ())
{
node_l->logger.try_log (boost::str (boost::format ("Unable complete callback: %1%:%2%: %3%") % address % port % ec.message ()));
}
node_l->logger.error (nano::log::type::rpc_callbacks, "Unable to complete callback: {}:{} ({})", address, port, ec.message ());
node_l->stats.inc (nano::stat::type::error, nano::stat::detail::http_callback, nano::stat::dir::out);
};
});
}
else
{
if (node_l->config.logging.callback_logging ())
{
node_l->logger.try_log (boost::str (boost::format ("Unable to send callback: %1%:%2%: %3%") % address % port % ec.message ()));
}
node_l->logger.error (nano::log::type::rpc_callbacks, "Unable to send callback: {}:{} ({})", address, port, ec.message ());
node_l->stats.inc (nano::stat::type::error, nano::stat::detail::http_callback, nano::stat::dir::out);
}
});
}
else
{
if (node_l->config.logging.callback_logging ())
{
node_l->logger.try_log (boost::str (boost::format ("Unable to connect to callback address: %1%:%2%: %3%") % address % port % ec.message ()));
}
node_l->logger.error (nano::log::type::rpc_callbacks, "Unable to connect to callback address: {}:{} ({})", address, port, ec.message ());
node_l->stats.inc (nano::stat::type::error, nano::stat::detail::http_callback, nano::stat::dir::out);
++i_a;
node_l->do_rpc_callback (i_a, address, port, target, body, resolver);
}
});
@ -655,7 +649,7 @@ void nano::node::start ()
network.port = tcp_listener->endpoint ().port ();
}
logger.always_log (boost::str (boost::format ("Node started with peering port `%1%`.") % network.port));
logger.info (nano::log::type::node, "Node peering port: {}", network.port.load ());
}
if (!flags.disable_backup)
@ -702,7 +696,7 @@ void nano::node::stop ()
return;
}
logger.always_log ("Node stopping");
logger.info (nano::log::type::node, "Node stopping...");
// Cancels ongoing work generation tasks, which may be blocking other threads
// No tasks may wait for work generation in I/O threads, or termination signal capturing will be unable to call node::stop()
@ -811,7 +805,7 @@ void nano::node::long_inactivity_cleanup ()
{
store.online_weight.clear (transaction);
store.peer.clear (transaction);
logger.always_log ("Removed records of peers and online weight after a long period of inactivity");
logger.info (nano::log::type::node, "Removed records of peers and online weight after a long period of inactivity");
}
}
@ -975,7 +969,7 @@ void nano::node::unchecked_cleanup ()
}
if (!cleaning_list.empty ())
{
logger.always_log (boost::str (boost::format ("Deleting %1% old unchecked blocks") % cleaning_list.size ()));
logger.info (nano::log::type::node, "Deleting {} old unchecked blocks", cleaning_list.size ());
}
// Delete old unchecked keys in batches
while (!cleaning_list.empty ())
@ -1056,7 +1050,7 @@ bool nano::node::collect_ledger_pruning_targets (std::deque<nano::block_hash> &
return !finish_transaction || last_account_a.is_zero ();
}
void nano::node::ledger_pruning (uint64_t const batch_size_a, bool bootstrap_weight_reached_a, bool log_to_cout_a)
void nano::node::ledger_pruning (uint64_t const batch_size_a, bool bootstrap_weight_reached_a)
{
uint64_t const max_depth (config.max_pruning_depth != 0 ? config.max_pruning_depth : std::numeric_limits<uint64_t>::max ());
uint64_t const cutoff_time (bootstrap_weight_reached_a ? nano::seconds_since_epoch () - config.max_pruning_age.count () : std::numeric_limits<uint64_t>::max ());
@ -1086,32 +1080,18 @@ void nano::node::ledger_pruning (uint64_t const batch_size_a, bool bootstrap_wei
pruning_targets.pop_front ();
}
pruned_count += transaction_write_count;
auto log_message (boost::str (boost::format ("%1% blocks pruned") % pruned_count));
if (!log_to_cout_a)
{
logger.try_log (log_message);
}
else
{
std::cout << log_message << std::endl;
}
logger.debug (nano::log::type::prunning, "Pruned blocks: {}", pruned_count);
}
}
auto const log_message (boost::str (boost::format ("Total recently pruned block count: %1%") % pruned_count));
if (!log_to_cout_a)
{
logger.always_log (log_message);
}
else
{
std::cout << log_message << std::endl;
}
logger.debug (nano::log::type::prunning, "Total recently pruned block count: {}", pruned_count);
}
void nano::node::ongoing_ledger_pruning ()
{
auto bootstrap_weight_reached (ledger.cache.block_count >= ledger.bootstrap_weight_max_blocks);
ledger_pruning (flags.block_processor_batch_size != 0 ? flags.block_processor_batch_size : 2 * 1024, bootstrap_weight_reached, false);
ledger_pruning (flags.block_processor_batch_size != 0 ? flags.block_processor_batch_size : 2 * 1024, bootstrap_weight_reached);
auto const ledger_pruning_interval (bootstrap_weight_reached ? config.max_pruning_age : std::min (config.max_pruning_age, std::chrono::seconds (15 * 60)));
auto this_l (shared ());
workers.add_timed_task (std::chrono::steady_clock::now () + ledger_pruning_interval, [this_l] () {
@ -1238,7 +1218,7 @@ void nano::node::add_initial_peers ()
{
if (flags.disable_add_initial_peers)
{
logger.always_log ("Skipping add_initial_peers because disable_add_initial_peers is set");
logger.warn (nano::log::type::node, "Not adding initial peers because `disable_add_initial_peers` flag is set");
return;
}
@ -1318,12 +1298,12 @@ void nano::node::receive_confirmed (store::transaction const & block_transaction
{
if (!ledger.block_or_pruned_exists (block_transaction_a, hash_a))
{
logger.try_log (boost::str (boost::format ("Confirmed block is missing: %1%") % hash_a.to_string ()));
debug_assert (false && "Confirmed block is missing");
logger.warn (nano::log::type::node, "Confirmed block is missing: {}", hash_a.to_string ());
debug_assert (false, "Confirmed block is missing");
}
else
{
logger.try_log (boost::str (boost::format ("Block %1% has already been received") % hash_a.to_string ()));
logger.warn (nano::log::type::node, "Block has already been received: {}", hash_a.to_string ());
}
}
}
@ -1495,6 +1475,12 @@ nano::telemetry_data nano::node::local_telemetry () const
return telemetry_data;
}
std::string nano::node::make_logger_identifier (const nano::keypair & node_id)
{
// Node identifier consists of first 10 characters of node id
return node_id.pub.to_node_id ().substr (0, 10);
}
/*
* node_wrapper
*/
@ -1504,13 +1490,14 @@ nano::node_wrapper::node_wrapper (std::filesystem::path const & path_a, std::fil
io_context (std::make_shared<boost::asio::io_context> ()),
work{ network_params.network, 1 }
{
boost::system::error_code error_chmod;
/*
* @warning May throw a filesystem exception
*/
std::filesystem::create_directories (path_a);
boost::system::error_code error_chmod;
nano::set_secure_perm_directory (path_a, error_chmod);
nano::daemon_config daemon_config{ path_a, network_params };
auto error = nano::read_node_config_toml (config_path_a, daemon_config, node_flags_a.config_overrides);
if (error)
@ -1527,8 +1514,6 @@ nano::node_wrapper::node_wrapper (std::filesystem::path const & path_a, std::fil
auto & node_config = daemon_config.node;
node_config.peering_port = 24000;
node_config.logging.max_size = std::numeric_limits<std::uintmax_t>::max ();
node_config.logging.init (path_a);
node = std::make_shared<nano::node> (*io_context, path_a, node_config, work, node_flags_a);
}

View file

@ -1,6 +1,7 @@
#pragma once
#include <nano/lib/config.hpp>
#include <nano/lib/logging.hpp>
#include <nano/lib/stats.hpp>
#include <nano/lib/thread_pool.hpp>
#include <nano/lib/work.hpp>
@ -69,7 +70,7 @@ outbound_bandwidth_limiter::config outbound_bandwidth_limiter_config (node_confi
class node final : public std::enable_shared_from_this<nano::node>
{
public:
node (boost::asio::io_context &, uint16_t, std::filesystem::path const &, nano::logging const &, nano::work_pool &, nano::node_flags = nano::node_flags (), unsigned seq = 0);
node (boost::asio::io_context &, uint16_t, std::filesystem::path const &, nano::work_pool &, nano::node_flags = nano::node_flags (), unsigned seq = 0);
node (boost::asio::io_context &, std::filesystem::path const &, nano::node_config const &, nano::work_pool &, nano::node_flags = nano::node_flags (), unsigned seq = 0);
~node ();
@ -106,7 +107,7 @@ public:
void bootstrap_wallet ();
void unchecked_cleanup ();
bool collect_ledger_pruning_targets (std::deque<nano::block_hash> &, nano::account &, uint64_t const, uint64_t const, uint64_t const);
void ledger_pruning (uint64_t const, bool, bool);
void ledger_pruning (uint64_t const, bool);
void ongoing_ledger_pruning ();
int price (nano::uint128_t const &, int);
// The default difficulty updates to base only when the first epoch_2 block is processed
@ -139,18 +140,19 @@ public:
nano::telemetry_data local_telemetry () const;
public:
const nano::keypair node_id;
nano::write_database_queue write_database_queue;
boost::asio::io_context & io_ctx;
boost::latch node_initialized_latch;
nano::node_config config;
nano::network_params & network_params;
nano::logger logger;
nano::stats stats;
nano::thread_pool workers;
nano::thread_pool bootstrap_workers;
nano::node_flags flags;
nano::work_pool & work;
nano::distributed_work_factory distributed_work;
nano::logger_mt logger;
std::unique_ptr<nano::store::component> store_impl;
nano::store::component & store;
nano::unchecked_map unchecked;
@ -174,7 +176,6 @@ public:
nano::block_processor block_processor;
nano::block_arrival block_arrival;
nano::local_vote_history history;
nano::keypair node_id;
nano::block_uniquer block_uniquer;
nano::vote_uniquer vote_uniquer;
nano::confirmation_height_processor confirmation_height_processor;
@ -226,9 +227,12 @@ public: // Testing convenience functions
private:
void long_inactivity_cleanup ();
static std::string make_logger_identifier (nano::keypair const & node_id);
};
nano::keypair load_or_create_node_id (std::filesystem::path const & application_path, nano::logger_mt & logger);
nano::keypair load_or_create_node_id (std::filesystem::path const & application_path);
std::unique_ptr<container_info_component> collect_container_info (node & node, std::string const & name);
nano::node_flags const & inactive_node_flag_defaults ();

View file

@ -21,15 +21,14 @@ std::string const default_test_peer_network = nano::get_env_or_default ("NANO_DE
}
nano::node_config::node_config (nano::network_params & network_params) :
node_config (std::nullopt, nano::logging (), network_params)
node_config (std::nullopt, network_params)
{
}
nano::node_config::node_config (const std::optional<uint16_t> & peering_port_a, nano::logging const & logging_a, nano::network_params & network_params) :
nano::node_config::node_config (const std::optional<uint16_t> & peering_port_a, nano::network_params & network_params) :
network_params{ network_params },
peering_port{ peering_port_a },
hinted_scheduler{ network_params.network },
logging{ logging_a },
websocket_config{ network_params.network },
ipc_config{ network_params.network },
external_address{ boost::asio::ip::address_v6{}.to_string () }
@ -168,10 +167,6 @@ nano::error nano::node_config::serialize_toml (nano::tomlconfig & toml) const
callback_l.put ("target", callback_target, "Callback target path.\ntype:string,uri");
toml.put_child ("httpcallback", callback_l);
nano::tomlconfig logging_l;
logging.serialize_toml (logging_l);
toml.put_child ("logging", logging_l);
nano::tomlconfig websocket_l;
websocket_config.serialize_toml (websocket_l);
toml.put_child ("websocket", websocket_l);
@ -223,12 +218,6 @@ nano::error nano::node_config::deserialize_toml (nano::tomlconfig & toml)
callback_l.get<std::string> ("target", callback_target);
}
if (toml.has_key ("logging"))
{
auto logging_l (toml.get_required_child ("logging"));
logging.deserialize_toml (logging_l);
}
if (toml.has_key ("websocket"))
{
auto websocket_config_l (toml.get_required_child ("websocket"));

View file

@ -4,12 +4,12 @@
#include <nano/lib/diagnosticsconfig.hpp>
#include <nano/lib/errors.hpp>
#include <nano/lib/lmdbconfig.hpp>
#include <nano/lib/logging.hpp>
#include <nano/lib/numbers.hpp>
#include <nano/lib/rocksdbconfig.hpp>
#include <nano/lib/stats.hpp>
#include <nano/node/bootstrap/bootstrap_config.hpp>
#include <nano/node/ipc/ipc_config.hpp>
#include <nano/node/logging.hpp>
#include <nano/node/scheduler/hinted.hpp>
#include <nano/node/scheduler/optimistic.hpp>
#include <nano/node/vote_cache.hpp>
@ -39,18 +39,18 @@ class node_config
{
public:
node_config (nano::network_params & network_params = nano::dev::network_params);
node_config (const std::optional<uint16_t> &, nano::logging const &, nano::network_params & network_params = nano::dev::network_params);
node_config (const std::optional<uint16_t> &, nano::network_params & network_params = nano::dev::network_params);
nano::error serialize_toml (nano::tomlconfig &) const;
nano::error deserialize_toml (nano::tomlconfig &);
bool upgrade_json (unsigned, nano::jsonconfig &);
nano::account random_representative () const;
nano::network_params network_params;
std::optional<uint16_t> peering_port{};
nano::scheduler::optimistic_config optimistic_scheduler;
nano::scheduler::hinted_config hinted_scheduler;
nano::logging logging;
std::vector<std::pair<std::string, uint16_t>> work_peers;
std::vector<std::pair<std::string, uint16_t>> secondary_work_peers{ { "127.0.0.1", 8076 } }; /* Default of nano-pow-server */
std::vector<std::string> preconfigured_peers;

View file

@ -1,4 +1,5 @@
#include <nano/crypto_lib/random_pool.hpp>
#include <nano/lib/logging.hpp>
#include <nano/lib/work.hpp>
#include <nano/node/openclconfig.hpp>
#include <nano/node/openclwork.hpp>
@ -249,7 +250,7 @@ void nano::opencl_environment::dump (std::ostream & stream)
}
}
nano::opencl_work::opencl_work (bool & error_a, nano::opencl_config const & config_a, nano::opencl_environment & environment_a, nano::logger_mt & logger_a, nano::work_thresholds & work) :
nano::opencl_work::opencl_work (bool & error_a, nano::opencl_config const & config_a, nano::opencl_environment & environment_a, nano::logger & logger_a, nano::work_thresholds & work) :
config (config_a),
context (0),
attempt_buffer (0),
@ -343,85 +344,85 @@ nano::opencl_work::opencl_work (bool & error_a, nano::opencl_config const & conf
}
else
{
logger.always_log (boost::str (boost::format ("Bind argument 3 error %1%") % arg3_error));
logger.error (nano::log::type::opencl_work, "Bind argument 3 error: {}", arg3_error);
}
}
else
{
logger.always_log (boost::str (boost::format ("Bind argument 2 error %1%") % arg2_error));
logger.error (nano::log::type::opencl_work, "Bind argument 2 error: {}", arg2_error);
}
}
else
{
logger.always_log (boost::str (boost::format ("Bind argument 1 error %1%") % arg1_error));
logger.error (nano::log::type::opencl_work, "Bind argument 1 error: {}", arg1_error);
}
}
else
{
logger.always_log (boost::str (boost::format ("Bind argument 0 error %1%") % arg0_error));
logger.error (nano::log::type::opencl_work, "Bind argument 0 error: {}", arg0_error);
}
}
else
{
logger.always_log (boost::str (boost::format ("Create kernel error %1%") % kernel_error));
logger.error (nano::log::type::opencl_work, "Create kernel error: {}", kernel_error);
}
}
else
{
logger.always_log (boost::str (boost::format ("Build program error %1%") % clBuildProgramError));
logger.error (nano::log::type::opencl_work, "Build program error: {}", clBuildProgramError);
for (auto i (selected_devices.begin ()), n (selected_devices.end ()); i != n; ++i)
{
std::size_t log_size (0);
clGetProgramBuildInfo (program, *i, CL_PROGRAM_BUILD_LOG, 0, nullptr, &log_size);
std::vector<char> log (log_size);
clGetProgramBuildInfo (program, *i, CL_PROGRAM_BUILD_LOG, log.size (), log.data (), nullptr);
logger.always_log (log.data ());
logger.info (nano::log::type::opencl_work, "Device log: {}", log.data ());
}
}
}
else
{
logger.always_log (boost::str (boost::format ("Create program error %1%") % program_error));
logger.error (nano::log::type::opencl_work, "Create program error: {}", program_error);
}
}
else
{
logger.always_log (boost::str (boost::format ("Difficulty buffer error %1%") % difficulty_error));
logger.error (nano::log::type::opencl_work, "Difficulty buffer error: {}", difficulty_error);
}
}
else
{
logger.always_log (boost::str (boost::format ("Item buffer error %1%") % item_error));
logger.error (nano::log::type::opencl_work, "Item buffer error: {}", item_error);
}
}
else
{
logger.always_log (boost::str (boost::format ("Result buffer error %1%") % result_error));
logger.error (nano::log::type::opencl_work, "Result buffer error: {}", result_error);
}
}
else
{
logger.always_log (boost::str (boost::format ("Attempt buffer error %1%") % attempt_error));
logger.error (nano::log::type::opencl_work, "Attempt buffer error: {}", attempt_error);
}
}
else
{
logger.always_log (boost::str (boost::format ("Unable to create command queue %1%") % queue_error));
logger.error (nano::log::type::opencl_work, "Unable to create command queue: {}", queue_error);
}
}
else
{
logger.always_log (boost::str (boost::format ("Unable to create context %1%") % createContextError));
logger.error (nano::log::type::opencl_work, "Unable to create context: {}", createContextError);
}
}
else
{
logger.always_log (boost::str (boost::format ("Requested device %1%, and only have %2%") % config.device % platform.devices.size ()));
logger.error (nano::log::type::opencl_work, "Requested device {} and only have {}", config.device, platform.devices.size ());
}
}
else
{
logger.always_log (boost::str (boost::format ("Requested platform %1% and only have %2%") % config.platform % environment_a.platforms.size ()));
logger.error (nano::log::type::opencl_work, "Requested platform {} and only have {}", config.platform, environment_a.platforms.size ());
}
}
@ -480,37 +481,37 @@ boost::optional<uint64_t> nano::opencl_work::generate_work (nano::work_version c
else
{
error = true;
logger.always_log (boost::str (boost::format ("Error finishing queue %1%") % finishError));
logger.error (nano::log::type::opencl_work, "Error finishing queue: {}", finishError);
}
}
else
{
error = true;
logger.always_log (boost::str (boost::format ("Error reading result %1%") % read_error1));
logger.error (nano::log::type::opencl_work, "Error reading result: {}", read_error1);
}
}
else
{
error = true;
logger.always_log (boost::str (boost::format ("Error enqueueing kernel %1%") % enqueue_error));
logger.error (nano::log::type::opencl_work, "Error enqueueing kernel: {}", enqueue_error);
}
}
else
{
error = true;
logger.always_log (boost::str (boost::format ("Error writing item %1%") % write_error3));
logger.error (nano::log::type::opencl_work, "Error writing difficulty: {}", write_error3);
}
}
else
{
error = true;
logger.always_log (boost::str (boost::format ("Error writing item %1%") % write_error2));
logger.error (nano::log::type::opencl_work, "Error writing item: {}", write_error2);
}
}
else
{
error = true;
logger.always_log (boost::str (boost::format ("Error writing attempt %1%") % write_error1));
logger.error (nano::log::type::opencl_work, "Error writing attempt: {}", write_error1);
}
}
boost::optional<uint64_t> value;
@ -521,16 +522,18 @@ boost::optional<uint64_t> nano::opencl_work::generate_work (nano::work_version c
return value;
}
std::unique_ptr<nano::opencl_work> nano::opencl_work::create (bool create_a, nano::opencl_config const & config_a, nano::logger_mt & logger_a, nano::work_thresholds & work)
std::unique_ptr<nano::opencl_work> nano::opencl_work::create (bool create_a, nano::opencl_config const & config_a, nano::logger & logger_a, nano::work_thresholds & work)
{
std::unique_ptr<nano::opencl_work> result;
if (create_a)
{
auto error (false);
nano::opencl_environment environment (error);
std::stringstream stream;
environment.dump (stream);
logger_a.always_log (stream.str ());
logger_a.info (nano::log::type::opencl_work, "OpenCL environment: {}", stream.str ());
if (!error)
{
result.reset (new nano::opencl_work (error, config_a, environment, logger_a, work));

View file

@ -21,7 +21,7 @@
namespace nano
{
extern bool opencl_loaded;
class logger_mt;
class logger;
class opencl_platform
{
public:
@ -40,11 +40,11 @@ class work_pool;
class opencl_work
{
public:
opencl_work (bool &, nano::opencl_config const &, nano::opencl_environment &, nano::logger_mt &, nano::work_thresholds & work);
opencl_work (bool &, nano::opencl_config const &, nano::opencl_environment &, nano::logger &, nano::work_thresholds & work);
~opencl_work ();
boost::optional<uint64_t> generate_work (nano::work_version const, nano::root const &, uint64_t const);
boost::optional<uint64_t> generate_work (nano::work_version const, nano::root const &, uint64_t const, std::atomic<int> &);
static std::unique_ptr<opencl_work> create (bool, nano::opencl_config const &, nano::logger_mt &, nano::work_thresholds & work);
static std::unique_ptr<opencl_work> create (bool, nano::opencl_config const &, nano::logger &, nano::work_thresholds & work);
nano::opencl_config const & config;
nano::mutex mutex;
cl_context context;
@ -56,7 +56,7 @@ public:
cl_kernel kernel;
cl_command_queue queue;
nano::xorshift1024star rand;
nano::logger_mt & logger;
nano::logger & logger;
nano::work_thresholds & work;
};
}

View file

@ -60,17 +60,19 @@ void nano::port_mapping::refresh_devices ()
std::array<char, 64> local_address_l;
local_address_l.fill (0);
auto igd_error_l (UPNP_GetValidIGD (upnp_l.devices, &upnp_l.urls, &upnp_l.data, local_address_l.data (), sizeof (local_address_l)));
if (check_count % 15 == 0 || node.config.logging.upnp_details_logging ())
// Bump logging level periodically
node.logger.log ((check_count % 15 == 0) ? nano::log::level::info : nano::log::level::debug,
nano::log::type::upnp, "UPnP local address {}, discovery: {}, IGD search: {}",
local_address_l.data (),
discover_error_l,
igd_error_l);
for (auto i (upnp_l.devices); i != nullptr; i = i->pNext)
{
node.logger.always_log (boost::str (boost::format ("UPnP local address: %1%, discovery: %2%, IGD search: %3%") % local_address_l.data () % discover_error_l % igd_error_l));
if (node.config.logging.upnp_details_logging ())
{
for (auto i (upnp_l.devices); i != nullptr; i = i->pNext)
{
node.logger.always_log (boost::str (boost::format ("UPnP device url: %1% st: %2% usn: %3%") % i->descURL % i->st % i->usn));
}
}
node.logger.debug (nano::log::type::upnp, "UPnP device url: {}, st: {}, usn: {}", i->descURL, i->st, i->usn);
}
// Update port mapping
nano::lock_guard<nano::mutex> guard_l (mutex);
upnp = std::move (upnp_l);
@ -114,14 +116,23 @@ void nano::port_mapping::refresh_mapping ()
if (add_port_mapping_error_l == UPNPCOMMAND_SUCCESS)
{
protocol.external_port = static_cast<uint16_t> (std::atoi (config_port_l.data ()));
auto fmt = boost::format ("UPnP %1% %2%:%3% mapped to %4%") % protocol.name % protocol.external_address % config_port_l % node_port_l;
node.logger.always_log (boost::str (fmt));
node.logger.info (nano::log::type::upnp, "UPnP {} {}:{} mapped to: {}",
protocol.name,
protocol.external_address.to_string (),
config_port_l,
node_port_l);
}
else
{
protocol.external_port = 0;
auto fmt = boost::format ("UPnP %1% %2%:%3% FAILED") % protocol.name % add_port_mapping_error_l % strupnperror (add_port_mapping_error_l);
node.logger.always_log (boost::str (fmt));
node.logger.warn (nano::log::type::upnp, "UPnP {} {}:{} failed: {} ({})",
protocol.name,
protocol.external_address.to_string (),
config_port_l,
add_port_mapping_error_l,
strupnperror (add_port_mapping_error_l));
}
}
}
@ -149,12 +160,19 @@ bool nano::port_mapping::check_lost_or_old_mapping ()
if (verify_port_mapping_error_l != UPNPCOMMAND_SUCCESS)
{
result_l = true;
node.logger.always_log (boost::str (boost::format ("UPNP_GetSpecificPortMappingEntry failed %1%: %2%") % verify_port_mapping_error_l % strupnperror (verify_port_mapping_error_l)));
node.logger.warn (nano::log::type::upnp, "UPnP get specific port mapping failed: {} ({})",
verify_port_mapping_error_l,
strupnperror (verify_port_mapping_error_l));
}
if (!recent_lease)
{
result_l = true;
node.logger.always_log (boost::str (boost::format ("UPnP leasing time getting old, remaining time: %1%, lease time: %2%, below the threshold: %3%") % remaining_from_port_mapping % lease_duration % lease_duration_divided_by_two));
node.logger.info (nano::log::type::upnp, "UPnP lease time getting old, remaining time: {}, lease time: {}, below the threshold: {}",
remaining_from_port_mapping,
lease_duration,
lease_duration_divided_by_two);
}
std::array<char, 64> external_address_l;
external_address_l.fill (0);
@ -168,12 +186,19 @@ bool nano::port_mapping::check_lost_or_old_mapping ()
else
{
protocol.external_address = boost::asio::ip::address_v4::any ();
node.logger.always_log (boost::str (boost::format ("UPNP_GetExternalIPAddress failed %1%: %2%") % verify_port_mapping_error_l % strupnperror (verify_port_mapping_error_l)));
}
if (node.config.logging.upnp_details_logging ())
{
node.logger.always_log (boost::str (boost::format ("UPnP %1% mapping verification response: %2%, external ip response: %3%, external ip: %4%, internal ip: %5%, remaining lease: %6%") % protocol.name % verify_port_mapping_error_l % external_ip_error_l % external_address_l.data () % address.to_string () % remaining_mapping_duration_l.data ()));
node.logger.warn (nano::log::type::upnp, "UPnP get external ip address failed: {} ({})",
external_ip_error_l,
strupnperror (external_ip_error_l));
}
node.logger.debug (nano::log::type::upnp, "UPnP {} mapping verification response: {}, external ip response: {}, external ip: {}, internal ip: {}, remaining lease: {}",
protocol.name,
verify_port_mapping_error_l,
external_ip_error_l,
external_address_l.data (),
address.to_string (),
remaining_mapping_duration_l.data ());
}
return result_l;
}
@ -194,15 +219,14 @@ void nano::port_mapping::check_mapping_loop ()
}
else
{
node.logger.always_log (boost::str (boost::format ("UPnP No need to refresh the mapping")));
node.logger.info (nano::log::type::upnp, "UPnP No need to refresh the mapping");
}
}
else
{
if (check_count < 10 || node.config.logging.upnp_details_logging ())
{
node.logger.always_log (boost::str (boost::format ("UPnP No IGD devices found")));
}
// Bump logging level periodically
node.logger.log ((check_count % 15 == 0) ? nano::log::level::info : nano::log::level::debug,
nano::log::type::upnp, "UPnP No IGD devices found");
}
// Check for new devices or after health_check_period
@ -225,11 +249,17 @@ void nano::port_mapping::stop ()
auto delete_error_l (UPNP_DeletePortMapping (upnp.urls.controlURL, upnp.data.first.servicetype, std::to_string (protocol.external_port).c_str (), protocol.name, address.to_string ().c_str ()));
if (delete_error_l)
{
node.logger.always_log (boost::str (boost::format ("UPnP shutdown %1% port mapping response: %2%") % protocol.name % delete_error_l));
node.logger.warn (nano::log::type::upnp, "UPnP shutdown {} port mapping failed: {} ({})",
protocol.name,
delete_error_l,
strupnperror (delete_error_l));
}
else
{
node.logger.always_log (boost::str (boost::format ("UPnP shutdown %1% port mapping successful: %2%:%3%") % protocol.name % protocol.external_address % protocol.external_port));
node.logger.info (nano::log::type::upnp, "UPnP shutdown {} port mapping successful: {}:{}",
protocol.name,
protocol.external_address.to_string (),
protocol.external_port);
}
}
}

View file

@ -45,20 +45,18 @@ void nano::rep_crawler::validate ()
if (channel->get_type () == nano::transport::transport_type::loopback)
{
if (node.config.logging.rep_crawler_logging ())
{
node.logger.try_log (boost::str (boost::format ("rep_crawler ignoring vote from loopback channel %1%") % channel->to_string ()));
}
node.logger.debug (nano::log::type::repcrawler, "Ignoring vote from loopback channel: {}", channel->to_string ());
continue;
}
nano::uint128_t rep_weight = node.ledger.weight (vote->account);
if (rep_weight < minimum)
{
if (node.config.logging.rep_crawler_logging ())
{
node.logger.try_log (boost::str (boost::format ("rep_crawler ignoring vote from account %1% with too little voting weight %2%") % vote->account.to_account () % rep_weight));
}
node.logger.debug (nano::log::type::repcrawler, "Ignoring vote from account {} with too little voting weight: {}",
vote->account.to_account (),
nano::util::to_str (rep_weight));
continue;
}
@ -95,12 +93,11 @@ void nano::rep_crawler::validate ()
if (inserted)
{
node.logger.try_log (boost::str (boost::format ("Found representative %1% at %2%") % vote->account.to_account () % channel->to_string ()));
node.logger.info (nano::log::type::repcrawler, "Found representative {} at {}", vote->account.to_account (), channel->to_string ());
}
if (updated)
{
node.logger.try_log (boost::str (boost::format ("Updated representative %1% at %2% (was at: %3%)") % vote->account.to_account () % channel->to_string () % prev_channel->to_string ()));
node.logger.warn (nano::log::type::repcrawler, "Updated representative {} at {} (was at: {})", vote->account.to_account (), channel->to_string (), prev_channel->to_string ());
}
}
}

View file

@ -22,23 +22,20 @@ void nano::transport::channel::send (nano::message & message_a, std::function<vo
auto should_pass (node.outbound_limiter.should_pass (buffer.size (), to_bandwidth_limit_type (traffic_type)));
if (!is_droppable_by_limiter || should_pass)
{
send_buffer (buffer, callback_a, drop_policy_a, traffic_type);
node.stats.inc (nano::stat::type::message, detail, nano::stat::dir::out);
send_buffer (buffer, callback_a, drop_policy_a, traffic_type);
}
else
{
node.stats.inc (nano::stat::type::drop, detail, nano::stat::dir::out);
if (callback_a)
{
node.background ([callback_a] () {
callback_a (boost::system::errc::make_error_code (boost::system::errc::not_supported), 0);
});
}
node.stats.inc (nano::stat::type::drop, detail, nano::stat::dir::out);
if (node.config.logging.network_packet_logging ())
{
node.logger.always_log (boost::str (boost::format ("%1% of size %2% dropped") % nano::to_string (detail) % buffer.size ()));
}
}
}
@ -60,4 +57,4 @@ nano::endpoint nano::transport::channel::get_peering_endpoint () const
lock.unlock ();
return get_endpoint ();
}
}
}

View file

@ -1,6 +1,8 @@
#include <nano/node/node.hpp>
#include <nano/node/transport/message_deserializer.hpp>
#include <magic_enum.hpp>
nano::transport::message_deserializer::message_deserializer (nano::network_constants const & network_constants_a, nano::network_filter & publish_filter_a, nano::block_uniquer & block_uniquer_a, nano::vote_uniquer & vote_uniquer_a,
read_query read_op) :
read_buffer{ std::make_shared<std::vector<uint8_t>> () },
@ -380,8 +382,10 @@ std::unique_ptr<nano::asc_pull_ack> nano::transport::message_deserializer::deser
return {};
}
nano::stat::detail nano::transport::message_deserializer::to_stat_detail (parse_status status)
nano::stat::detail nano::to_stat_detail (nano::transport::message_deserializer::parse_status status)
{
using parse_status = nano::transport::message_deserializer::parse_status;
// Keep additional `break` for readability
switch (status)
{
@ -449,74 +453,7 @@ nano::stat::detail nano::transport::message_deserializer::to_stat_detail (parse_
return {};
}
std::string nano::transport::message_deserializer::to_string (parse_status status)
std::string_view nano::to_string (nano::transport::message_deserializer::parse_status status)
{
// Keep additional `break` for readability
switch (status)
{
case parse_status::none:
return "none";
break;
case parse_status::success:
return "success";
break;
case parse_status::insufficient_work:
return "insufficient_work";
break;
case parse_status::invalid_header:
return "invalid_header";
break;
case parse_status::invalid_message_type:
return "invalid_message_type";
break;
case parse_status::invalid_keepalive_message:
return "invalid_keepalive_message";
break;
case parse_status::invalid_publish_message:
return "invalid_publish_message";
break;
case parse_status::invalid_confirm_req_message:
return "invalid_confirm_req_message";
break;
case parse_status::invalid_confirm_ack_message:
return "invalid_confirm_ack_message";
break;
case parse_status::invalid_node_id_handshake_message:
return "invalid_node_id_handshake_message";
break;
case parse_status::invalid_telemetry_req_message:
return "invalid_telemetry_req_message";
break;
case parse_status::invalid_telemetry_ack_message:
return "invalid_telemetry_ack_message";
break;
case parse_status::invalid_bulk_pull_message:
return "invalid_bulk_pull_message";
break;
case parse_status::invalid_bulk_pull_account_message:
return "invalid_bulk_pull_account_message";
break;
case parse_status::invalid_frontier_req_message:
return "invalid_frontier_req_message";
break;
case parse_status::invalid_asc_pull_req_message:
return "invalid_asc_pull_req_message";
break;
case parse_status::invalid_asc_pull_ack_message:
return "invalid_asc_pull_ack_message";
break;
case parse_status::invalid_network:
return "invalid_network";
break;
case parse_status::outdated_version:
return "outdated_version";
break;
case parse_status::duplicate_publish_message:
return "duplicate_publish_message";
break;
case parse_status::message_size_too_big:
return "message_size_too_big";
break;
}
return "n/a";
return magic_enum::enum_name (status);
}

View file

@ -89,11 +89,9 @@ namespace transport
nano::block_uniquer & block_uniquer_m;
nano::vote_uniquer & vote_uniquer_m;
read_query read_op;
public:
static stat::detail to_stat_detail (parse_status);
static std::string to_string (parse_status);
};
}
}
nano::stat::detail to_stat_detail (nano::transport::message_deserializer::parse_status);
std::string_view to_string (nano::transport::message_deserializer::parse_status);
}

View file

@ -54,6 +54,7 @@ void nano::transport::socket::async_connect (nano::tcp_endpoint const & endpoint
this_l->tcp_socket.async_connect (endpoint_a,
boost::asio::bind_executor (this_l->strand,
[this_l, callback = std::move (callback_a), endpoint_a] (boost::system::error_code const & ec) {
this_l->remote = endpoint_a;
if (ec)
{
this_l->node.stats.inc (nano::stat::type::tcp, nano::stat::detail::tcp_connect_error, nano::stat::dir::in);
@ -62,9 +63,13 @@ void nano::transport::socket::async_connect (nano::tcp_endpoint const & endpoint
else
{
this_l->set_last_completion ();
{
// Best effort attempt to get endpoint address
boost::system::error_code ec;
this_l->local = this_l->tcp_socket.local_endpoint (ec);
}
this_l->node.observers.socket_connected.notify (*this_l);
}
this_l->remote = endpoint_a;
this_l->node.observers.socket_connected.notify (*this_l);
callback (ec);
}));
}
@ -241,23 +246,22 @@ void nano::transport::socket::ongoing_checkup ()
if (this_l->endpoint_type () == endpoint_type_t::server && (now - this_l->last_receive_time_or_init) > static_cast<uint64_t> (this_l->silent_connection_tolerance_time.count ()))
{
this_l->node.stats.inc (nano::stat::type::tcp, nano::stat::detail::tcp_silent_connection_drop, nano::stat::dir::in);
condition_to_disconnect = true;
}
// if there is no activity for timeout seconds then disconnect
if ((now - this_l->last_completion_time_or_init) > this_l->timeout)
{
this_l->node.stats.inc (nano::stat::type::tcp, nano::stat::detail::tcp_io_timeout_drop,
this_l->endpoint_type () == endpoint_type_t::server ? nano::stat::dir::in : nano::stat::dir::out);
this_l->node.stats.inc (nano::stat::type::tcp, nano::stat::detail::tcp_io_timeout_drop, this_l->endpoint_type () == endpoint_type_t::server ? nano::stat::dir::in : nano::stat::dir::out);
condition_to_disconnect = true;
}
if (condition_to_disconnect)
{
if (this_l->node.config.logging.network_timeout_logging ())
{
this_l->node.logger.try_log (boost::str (boost::format ("Disconnecting from %1% due to timeout") % this_l->remote));
}
this_l->node.logger.debug (nano::log::type::tcp_server, "Closing socket due to timeout ({})", nano::util::to_str (this_l->remote));
this_l->timed_out = true;
this_l->close ();
}
@ -330,19 +334,21 @@ void nano::transport::socket::close_internal ()
if (ec)
{
node.logger.try_log ("Failed to close socket gracefully: ", ec.message ());
node.stats.inc (nano::stat::type::bootstrap, nano::stat::detail::error_socket_close);
node.stats.inc (nano::stat::type::socket, nano::stat::detail::error_socket_close);
node.logger.error (nano::log::type::socket, "Failed to close socket gracefully: {} ({})", ec.message (), nano::util::to_str (remote));
}
}
nano::tcp_endpoint nano::transport::socket::remote_endpoint () const
{
// Using cached value to avoid calling tcp_socket.remote_endpoint() which may be invalid (throw) after closing the socket
return remote;
}
nano::tcp_endpoint nano::transport::socket::local_endpoint () const
{
return tcp_socket.local_endpoint ();
// Using cached value to avoid calling tcp_socket.local_endpoint() which may be invalid (throw) after closing the socket
return local;
}
/*

View file

@ -4,6 +4,7 @@
#include <nano/boost/asio/strand.hpp>
#include <nano/lib/asio.hpp>
#include <nano/lib/locks.hpp>
#include <nano/lib/logging.hpp>
#include <nano/lib/timer.hpp>
#include <nano/node/transport/traffic_type.hpp>
@ -157,6 +158,7 @@ protected:
/** The other end of the connection */
boost::asio::ip::tcp::endpoint remote;
boost::asio::ip::tcp::endpoint local;
/** number of seconds of inactivity that causes a socket timeout
* activity is any successful connect, send or receive event

View file

@ -98,7 +98,7 @@ void nano::transport::channel_tcp::send_buffer (nano::shared_const_buffer const
std::string nano::transport::channel_tcp::to_string () const
{
return boost::str (boost::format ("%1%") % get_tcp_endpoint ());
return nano::util::to_str (get_tcp_endpoint ());
}
void nano::transport::channel_tcp::set_endpoint ()
@ -555,10 +555,9 @@ void nano::transport::tcp_channels::start_tcp (nano::endpoint const & endpoint_a
auto query = node_l->network.prepare_handshake_query (endpoint_a);
nano::node_id_handshake message{ node_l->network_params.network, query };
if (node_l->config.logging.network_node_id_handshake_logging ())
{
node_l->logger.try_log (boost::str (boost::format ("Node ID handshake request sent with node ID %1% to %2%: query %3%") % node_l->node_id.pub.to_node_id () % endpoint_a % (query ? query->cookie.to_string () : "not set")));
}
node_l->logger.debug (nano::log::type::tcp, "Handshake sent to: {} (query: {})",
nano::util::to_str (endpoint_a),
(query ? query->cookie.to_string () : "<none>"));
channel->set_endpoint ();
std::shared_ptr<std::vector<uint8_t>> receive_buffer (std::make_shared<std::vector<uint8_t>> ());
@ -572,30 +571,25 @@ void nano::transport::tcp_channels::start_tcp (nano::endpoint const & endpoint_a
}
else
{
node_l->logger.debug (nano::log::type::tcp, "Error sending handshake to: {} ({})", nano::util::to_str (endpoint_a), ec.message ());
if (auto socket_l = channel->socket.lock ())
{
socket_l->close ();
}
if (node_l->config.logging.network_node_id_handshake_logging ())
{
node_l->logger.try_log (boost::str (boost::format ("Error sending node_id_handshake to %1%: %2%") % endpoint_a % ec.message ()));
}
}
}
});
}
else
{
if (node_l->config.logging.network_logging ())
if (ec)
{
if (ec)
{
node_l->logger.try_log (boost::str (boost::format ("Error connecting to %1%: %2%") % endpoint_a % ec.message ()));
}
else
{
node_l->logger.try_log (boost::str (boost::format ("Error connecting to %1%") % endpoint_a));
}
node_l->logger.debug (nano::log::type::tcp, "Error connecting to: {} ({})", nano::util::to_str (endpoint_a), ec.message ());
}
else
{
node_l->logger.debug (nano::log::type::tcp, "Error connecting to: {}", nano::util::to_str (endpoint_a));
}
}
}
@ -633,10 +627,8 @@ void nano::transport::tcp_channels::start_tcp_receive_node_id (std::shared_ptr<n
}
if (ec || !channel_a)
{
if (node_l->config.logging.network_node_id_handshake_logging ())
{
node_l->logger.try_log (boost::str (boost::format ("Error reading node_id_handshake from %1%: %2%") % endpoint_a % ec.message ()));
}
node_l->logger.debug (nano::log::type::tcp, "Error reading handshake from: {} ({})", nano::util::to_str (endpoint_a), ec.message ());
cleanup_node_id_handshake_socket (endpoint_a);
return;
}
@ -646,10 +638,8 @@ void nano::transport::tcp_channels::start_tcp_receive_node_id (std::shared_ptr<n
// the header type should in principle be checked after checking the network bytes and the version numbers, I will not change it here since the benefits do not outweight the difficulties
if (error || message->type () != nano::message_type::node_id_handshake)
{
if (node_l->config.logging.network_node_id_handshake_logging ())
{
node_l->logger.try_log (boost::str (boost::format ("Error reading node_id_handshake message header from %1%") % endpoint_a));
}
node_l->logger.debug (nano::log::type::tcp, "Error reading handshake header from: {} ({})", nano::util::to_str (endpoint_a), ec.message ());
cleanup_node_id_handshake_socket (endpoint_a);
return;
}
@ -678,10 +668,8 @@ void nano::transport::tcp_channels::start_tcp_receive_node_id (std::shared_ptr<n
if (error || !handshake.response || !handshake.query)
{
if (node_l->config.logging.network_node_id_handshake_logging ())
{
node_l->logger.try_log (boost::str (boost::format ("Error reading node_id_handshake from %1%") % endpoint_a));
}
node_l->logger.debug (nano::log::type::tcp, "Error reading handshake payload from: {} ({})", nano::util::to_str (endpoint_a), ec.message ());
cleanup_node_id_handshake_socket (endpoint_a);
return;
}
@ -714,10 +702,9 @@ void nano::transport::tcp_channels::start_tcp_receive_node_id (std::shared_ptr<n
auto response = node_l->network.prepare_handshake_response (*handshake.query, handshake.is_v2 ());
nano::node_id_handshake handshake_response (node_l->network_params.network, std::nullopt, response);
if (node_l->config.logging.network_node_id_handshake_logging ())
{
node_l->logger.try_log (boost::str (boost::format ("Node ID handshake response sent with node ID %1% to %2%: query %3%") % node_l->node_id.pub.to_node_id () % endpoint_a % handshake.query->cookie.to_string ()));
}
node_l->logger.debug (nano::log::type::tcp, "Handshake response sent to {} (query: {})",
nano::util::to_str (endpoint_a),
handshake.query->cookie.to_string ());
channel_a->send (handshake_response, [node_w, channel_a, endpoint_a, cleanup_node_id_handshake_socket] (boost::system::error_code const & ec, std::size_t size_a) {
auto node_l = node_w.lock ();
@ -727,10 +714,8 @@ void nano::transport::tcp_channels::start_tcp_receive_node_id (std::shared_ptr<n
}
if (ec || !channel_a)
{
if (node_l->config.logging.network_node_id_handshake_logging ())
{
node_l->logger.try_log (boost::str (boost::format ("Error sending node_id_handshake to %1%: %2%") % endpoint_a % ec.message ()));
}
node_l->logger.debug (nano::log::type::tcp, "Error sending handshake response to: {} ({})", nano::util::to_str (endpoint_a), ec.message ());
cleanup_node_id_handshake_socket (endpoint_a);
return;
}

View file

@ -56,7 +56,7 @@ void nano::transport::tcp_listener::start (std::function<bool (std::shared_ptr<n
}
if (ec)
{
node.logger.always_log (boost::str (boost::format ("Network: Error while binding for incoming TCP/bootstrap on port %1%: %2%") % acceptor.local_endpoint ().port () % ec.message ()));
node.logger.critical (nano::log::type::tcp_listener, "Error while binding for incoming TCP: {} (port: {})", ec.message (), acceptor.local_endpoint ().port ());
throw std::runtime_error (ec.message ());
}
@ -125,7 +125,7 @@ void nano::transport::tcp_listener::on_connection (std::function<bool (std::shar
boost::asio::post (strand, boost::asio::bind_executor (strand, [this_l = shared_from_this (), callback = std::move (callback_a)] () mutable {
if (!this_l->acceptor.is_open ())
{
this_l->node.logger.always_log ("Network: Acceptor is not open");
this_l->node.logger.error (nano::log::type::tcp_listener, "Acceptor is not open");
return;
}
@ -138,20 +138,18 @@ void nano::transport::tcp_listener::on_connection (std::function<bool (std::shar
if (this_l->connections_per_address.size () >= this_l->max_inbound_connections)
{
this_l->node.logger.try_log ("Network: max_inbound_connections reached, unable to open new connection");
this_l->node.stats.inc (nano::stat::type::tcp, nano::stat::detail::tcp_accept_failure, nano::stat::dir::in);
this_l->node.logger.debug (nano::log::type::tcp_listener, "Max connections reached ({}), unable to open new connection", this_l->connections_per_address.size ());
this_l->on_connection_requeue_delayed (std::move (cbk));
return;
}
if (this_l->limit_reached_for_incoming_ip_connections (new_connection))
{
auto const remote_ip_address = new_connection->remote_endpoint ().address ();
auto const log_message = boost::str (
boost::format ("Network: max connections per IP (max_peers_per_ip) was reached for %1%, unable to open new connection")
% remote_ip_address.to_string ());
this_l->node.logger.try_log (log_message);
this_l->node.stats.inc (nano::stat::type::tcp, nano::stat::detail::tcp_max_per_ip, nano::stat::dir::in);
this_l->node.logger.debug (nano::log::type::tcp_listener, "Max connections per IP reached ({}), unable to open new connection", new_connection->remote_endpoint ().address ().to_string ());
this_l->on_connection_requeue_delayed (std::move (cbk));
return;
}
@ -161,18 +159,24 @@ void nano::transport::tcp_listener::on_connection (std::function<bool (std::shar
auto const remote_ip_address = new_connection->remote_endpoint ().address ();
debug_assert (remote_ip_address.is_v6 ());
auto const remote_subnet = socket_functions::get_ipv6_subnet_address (remote_ip_address.to_v6 (), this_l->node.network_params.network.max_peers_per_subnetwork);
auto const log_message = boost::str (
boost::format ("Network: max connections per subnetwork (max_peers_per_subnetwork) was reached for subnetwork %1% (remote IP: %2%), unable to open new connection")
% remote_subnet.canonical ().to_string ()
% remote_ip_address.to_string ());
this_l->node.logger.try_log (log_message);
this_l->node.stats.inc (nano::stat::type::tcp, nano::stat::detail::tcp_max_per_subnetwork, nano::stat::dir::in);
this_l->node.logger.debug (nano::log::type::tcp_listener, "Max connections per subnetwork reached (subnetwork: {}, ip: {}), unable to open new connection",
remote_subnet.canonical ().to_string (),
remote_ip_address.to_string ());
this_l->on_connection_requeue_delayed (std::move (cbk));
return;
}
if (!ec_a)
{
{
// Best effort attempt to get endpoint addresses
boost::system::error_code ec;
new_connection->local = new_connection->tcp_socket.local_endpoint (ec);
}
// Make sure the new connection doesn't idle. Note that in most cases, the callback is going to start
// an IO operation immediately, which will start a timer.
new_connection->start ();
@ -185,13 +189,13 @@ void nano::transport::tcp_listener::on_connection (std::function<bool (std::shar
this_l->on_connection (std::move (cbk));
return;
}
this_l->node.logger.always_log ("Network: Stopping to accept connections");
this_l->node.logger.warn (nano::log::type::tcp_listener, "Stopping to accept new connections");
return;
}
// accept error
this_l->node.logger.try_log ("Network: Unable to accept connection: ", ec_a.message ());
this_l->node.stats.inc (nano::stat::type::tcp, nano::stat::detail::tcp_accept_failure, nano::stat::dir::in);
this_l->node.logger.error (nano::log::type::tcp_listener, "Unable to accept connection: {} ({})", ec_a.message (), new_connection->remote_endpoint ().address ().to_string ());
if (is_temporary_error (ec_a))
{
@ -208,7 +212,7 @@ void nano::transport::tcp_listener::on_connection (std::function<bool (std::shar
}
// No requeue if we reach here, no incoming socket connections will be handled
this_l->node.logger.always_log ("Network: Stopping to accept connections");
this_l->node.logger.warn (nano::log::type::tcp_listener, "Stopping to accept new connections");
}));
}));
}
@ -250,10 +254,7 @@ void nano::transport::tcp_listener::accept_action (boost::system::error_code con
else
{
node.stats.inc (nano::stat::type::tcp, nano::stat::detail::tcp_excluded);
if (node.config.logging.network_rejected_logging ())
{
node.logger.try_log ("Rejected connection from excluded peer ", socket_a->remote_endpoint ());
}
node.logger.debug (nano::log::type::tcp_server, "Rejected connection from excluded peer: {}", nano::util::to_str (socket_a->remote_endpoint ()));
}
}
@ -304,10 +305,8 @@ nano::transport::tcp_server::~tcp_server ()
{
return;
}
if (node->config.logging.bulk_pull_logging ())
{
node->logger.try_log ("Exiting incoming TCP/bootstrap server");
}
node->logger.debug (nano::log::type::tcp_server, "Exiting TCP server ({})", nano::util::to_str (remote_endpoint));
if (socket->type () == nano::transport::socket::type_t::bootstrap)
{
@ -340,6 +339,12 @@ void nano::transport::tcp_server::start ()
remote_endpoint = socket->remote_endpoint ();
debug_assert (remote_endpoint.port () != 0);
}
if (auto node_l = node.lock (); node_l)
{
node_l->logger.debug (nano::log::type::tcp_server, "Starting TCP server ({})", nano::util::to_str (remote_endpoint));
}
receive_message ();
}
@ -367,7 +372,12 @@ void nano::transport::tcp_server::receive_message ()
if (ec)
{
// IO error or critical error when deserializing message
node->stats.inc (nano::stat::type::error, nano::transport::message_deserializer::to_stat_detail (this_l->message_deserializer->status));
node->stats.inc (nano::stat::type::error, nano::to_stat_detail (this_l->message_deserializer->status));
node->logger.debug (nano::log::type::tcp_server, "Error reading message: {}, status: {} ({})",
ec.message (),
nano::to_string (this_l->message_deserializer->status),
nano::util::to_str (this_l->remote_endpoint));
this_l->stop ();
}
else
@ -393,11 +403,19 @@ void nano::transport::tcp_server::received_message (std::unique_ptr<nano::messag
{
// Error while deserializing message
debug_assert (message_deserializer->status != transport::message_deserializer::parse_status::success);
node->stats.inc (nano::stat::type::error, nano::transport::message_deserializer::to_stat_detail (message_deserializer->status));
node->stats.inc (nano::stat::type::error, nano::to_stat_detail (message_deserializer->status));
if (message_deserializer->status == transport::message_deserializer::parse_status::duplicate_publish_message)
{
node->stats.inc (nano::stat::type::filter, nano::stat::detail::duplicate_publish);
}
else
{
// Avoid too much noise about `duplicate_publish_message` errors
node->logger.debug (nano::log::type::tcp_server, "Error deserializing message: {} ({})",
nano::to_string (message_deserializer->status),
nano::util::to_str (remote_endpoint));
}
}
if (should_continue)
@ -448,6 +466,10 @@ bool nano::transport::tcp_server::process_message (std::unique_ptr<nano::message
else
{
// Neither handshake nor bootstrap received when in handshake mode
node->logger.debug (nano::log::type::tcp_server, "Neither handshake nor bootstrap received when in handshake mode: {} ({})",
nano::to_string (message->header.type),
nano::util::to_str (remote_endpoint));
return true;
}
}
@ -500,10 +522,8 @@ void nano::transport::tcp_server::handshake_message_visitor::node_id_handshake (
}
if (node->flags.disable_tcp_realtime)
{
if (node->config.logging.network_node_id_handshake_logging ())
{
node->logger.try_log (boost::str (boost::format ("Disabled realtime TCP for handshake %1%") % server->remote_endpoint));
}
node->logger.debug (nano::log::type::tcp_server, "Handshake attempted with disabled realtime TCP ({})", nano::util::to_str (server->remote_endpoint));
// Stop invalid handshake
server->stop ();
return;
@ -511,10 +531,8 @@ void nano::transport::tcp_server::handshake_message_visitor::node_id_handshake (
if (message.query && server->handshake_query_received)
{
if (node->config.logging.network_node_id_handshake_logging ())
{
node->logger.try_log (boost::str (boost::format ("Detected multiple node_id_handshake query from %1%") % server->remote_endpoint));
}
node->logger.debug (nano::log::type::tcp_server, "Detected multiple handshake queries ({})", nano::util::to_str (server->remote_endpoint));
// Stop invalid handshake
server->stop ();
return;
@ -522,10 +540,7 @@ void nano::transport::tcp_server::handshake_message_visitor::node_id_handshake (
server->handshake_query_received = true;
if (node->config.logging.network_node_id_handshake_logging ())
{
node->logger.try_log (boost::str (boost::format ("Received node_id_handshake message from %1%") % server->remote_endpoint));
}
node->logger.debug (nano::log::type::tcp_server, "Handshake query received ({})", nano::util::to_str (server->remote_endpoint));
if (message.query)
{
@ -569,10 +584,8 @@ void nano::transport::tcp_server::send_handshake_response (nano::node_id_handsha
}
if (ec)
{
if (node->config.logging.network_node_id_handshake_logging ())
{
node->logger.try_log (boost::str (boost::format ("Error sending node_id_handshake to %1%: %2%") % this_l->remote_endpoint % ec.message ()));
}
node->logger.debug (nano::log::type::tcp_server, "Error sending handshake response: {} ({})", ec.message (), nano::util::to_str (this_l->remote_endpoint));
// Stop invalid handshake
this_l->stop ();
}
@ -692,11 +705,6 @@ void nano::transport::tcp_server::bootstrap_message_visitor::bulk_pull (const na
return;
}
if (node->config.logging.bulk_pull_logging ())
{
node->logger.try_log (boost::str (boost::format ("Received bulk pull for %1% down to %2%, maximum of %3% from %4%") % message.start.to_string () % message.end.to_string () % message.count % server->remote_endpoint));
}
node->bootstrap_workers.push_task ([server = server, message = message] () {
// TODO: Add completion callback to bulk pull server
// TODO: There should be no need to re-copy message as unique pointer, refactor those bulk/frontier pull/push servers
@ -719,11 +727,6 @@ void nano::transport::tcp_server::bootstrap_message_visitor::bulk_pull_account (
return;
}
if (node->config.logging.bulk_pull_logging ())
{
node->logger.try_log (boost::str (boost::format ("Received bulk pull account for %1% with a minimum amount of %2%") % message.account.to_account () % nano::amount (message.minimum_amount).format_balance (nano::Mxrb_ratio, 10, true)));
}
node->bootstrap_workers.push_task ([server = server, message = message] () {
// TODO: Add completion callback to bulk pull server
// TODO: There should be no need to re-copy message as unique pointer, refactor those bulk/frontier pull/push servers
@ -757,10 +760,6 @@ void nano::transport::tcp_server::bootstrap_message_visitor::frontier_req (const
{
return;
}
if (node->config.logging.bulk_pull_logging ())
{
node->logger.try_log (boost::str (boost::format ("Received frontier request for %1% with age %2%") % message.start.to_string () % message.age));
}
node->bootstrap_workers.push_task ([server = server, message = message] () {
// TODO: There should be no need to re-copy message as unique pointer, refactor those bulk/frontier pull/push servers
@ -782,10 +781,8 @@ void nano::transport::tcp_server::timeout ()
}
if (socket->has_timed_out ())
{
if (node->config.logging.bulk_pull_logging ())
{
node->logger.try_log ("Closing incoming tcp / bootstrap server by timeout");
}
node->logger.debug (nano::log::type::tcp_server, "Closing TCP server due to timeout ({})", nano::util::to_str (remote_endpoint));
{
nano::lock_guard<nano::mutex> lock{ node->tcp_listener->mutex };
node->tcp_listener->connections.erase (this);
@ -820,6 +817,9 @@ bool nano::transport::tcp_server::to_bootstrap_connection ()
++node->tcp_listener->bootstrap_count;
socket->type_set (nano::transport::socket::type_t::bootstrap);
node->logger.debug (nano::log::type::tcp_server, "Switched to bootstrap mode ({})", nano::util::to_str (remote_endpoint));
return true;
}
@ -835,6 +835,9 @@ bool nano::transport::tcp_server::to_realtime_connection (nano::account const &
remote_node_id = node_id;
++node->tcp_listener->realtime_count;
socket->type_set (nano::transport::socket::type_t::realtime);
node->logger.debug (nano::log::type::tcp_server, "Switched to realtime mode ({})", nano::util::to_str (remote_endpoint));
return true;
}
return false;

View file

@ -1,4 +1,4 @@
#include <nano/lib/logger_mt.hpp>
#include <nano/lib/stats.hpp>
#include <nano/lib/timer.hpp>
#include <nano/node/active_transactions.hpp>
@ -15,7 +15,7 @@
#include <chrono>
using namespace std::chrono_literals;
nano::vote_processor::vote_processor (nano::active_transactions & active_a, nano::node_observers & observers_a, nano::stats & stats_a, nano::node_config & config_a, nano::node_flags & flags_a, nano::logger_mt & logger_a, nano::online_reps & online_reps_a, nano::rep_crawler & rep_crawler_a, nano::ledger & ledger_a, nano::network_params & network_params_a) :
nano::vote_processor::vote_processor (nano::active_transactions & active_a, nano::node_observers & observers_a, nano::stats & stats_a, nano::node_config & config_a, nano::node_flags & flags_a, nano::logger & logger_a, nano::online_reps & online_reps_a, nano::rep_crawler & rep_crawler_a, nano::ledger & ledger_a, nano::network_params & network_params_a) :
active (active_a),
observers (observers_a),
stats (stats_a),
@ -62,7 +62,8 @@ void nano::vote_processor::process_loop ()
condition.notify_all ();
log_this_iteration = false;
if (config.logging.network_logging () && votes_l.size () > 50)
// TODO: This is a temporary measure to prevent spamming the logs until we can implement a better solution
if (votes_l.size () > 1024 * 4)
{
/*
* Only log the timing information for this iteration if
@ -76,8 +77,12 @@ void nano::vote_processor::process_loop ()
if (log_this_iteration && elapsed.stop () > std::chrono::milliseconds (100))
{
logger.try_log (boost::str (boost::format ("Processed %1% votes in %2% milliseconds (rate of %3% votes per second)") % votes_l.size () % elapsed.value ().count () % ((votes_l.size () * 1000ULL) / elapsed.value ().count ())));
logger.debug (nano::log::type::vote_processor, "Processed {} votes in {} milliseconds (rate of {} votes per second)",
votes_l.size (),
elapsed.value ().count (),
((votes_l.size () * 1000ULL) / elapsed.value ().count ()));
}
lock.lock ();
}
else
@ -168,10 +173,7 @@ nano::vote_code nano::vote_processor::vote_blocking (std::shared_ptr<nano::vote>
stats.inc (nano::stat::type::vote, nano::stat::detail::vote_indeterminate);
break;
}
if (config.logging.vote_logging ())
{
logger.try_log (boost::str (boost::format ("Vote from: %1% timestamp: %2% duration %3%ms block(s): %4% status: %5%") % vote_a->account.to_account () % std::to_string (vote_a->timestamp ()) % std::to_string (vote_a->duration ().count ()) % vote_a->hashes_string () % status));
}
return result;
}
@ -197,7 +199,7 @@ void nano::vote_processor::flush ()
});
if (!success)
{
logger.always_log ("WARNING: vote_processor::flush timeout while waiting for flush");
logger.error (nano::log::type::vote_processor, "Flush timeout");
debug_assert (false && "vote_processor::flush timeout while waiting for flush");
}
}

View file

@ -20,7 +20,7 @@ namespace store
class node_observers;
class stats;
class node_config;
class logger_mt;
class logger;
class online_reps;
class rep_crawler;
class ledger;
@ -36,7 +36,7 @@ namespace transport
class vote_processor final
{
public:
vote_processor (nano::active_transactions & active_a, nano::node_observers & observers_a, nano::stats & stats_a, nano::node_config & config_a, nano::node_flags & flags_a, nano::logger_mt & logger_a, nano::online_reps & online_reps_a, nano::rep_crawler & rep_crawler_a, nano::ledger & ledger_a, nano::network_params & network_params_a);
vote_processor (nano::active_transactions & active_a, nano::node_observers & observers_a, nano::stats & stats_a, nano::node_config & config_a, nano::node_flags & flags_a, nano::logger &, nano::online_reps & online_reps_a, nano::rep_crawler & rep_crawler_a, nano::ledger & ledger_a, nano::network_params & network_params_a);
/** Returns false if the vote was processed */
bool vote (std::shared_ptr<nano::vote> const &, std::shared_ptr<nano::transport::channel> const &);
@ -60,7 +60,7 @@ private:
nano::node_observers & observers;
nano::stats & stats;
nano::node_config & config;
nano::logger_mt & logger;
nano::logger & logger;
nano::online_reps & online_reps;
nano::rep_crawler & rep_crawler;
nano::ledger & ledger;

View file

@ -699,16 +699,17 @@ bool nano::wallet::enter_password (store::transaction const & transaction_a, std
auto result (store.attempt_password (transaction_a, password_a));
if (!result)
{
wallets.node.logger.info (nano::log::type::wallet, "Wallet unlocked");
auto this_l = shared_from_this ();
wallets.queue_wallet_action (nano::wallets::high_priority, this_l, [this_l] (nano::wallet & wallet) {
// Wallets must survive node lifetime
this_l->search_receivable (this_l->wallets.tx_begin_read ());
});
wallets.node.logger.try_log ("Wallet unlocked");
}
else
{
wallets.node.logger.try_log ("Invalid password, wallet locked");
wallets.node.logger.warn (nano::log::type::wallet, "Invalid password, wallet locked");
}
lock_observer (result, password_a.empty ());
return result;
@ -865,7 +866,7 @@ std::shared_ptr<nano::block> nano::wallet::receive_action (nano::block_hash cons
}
else
{
wallets.node.logger.try_log ("Unable to receive, wallet locked");
wallets.node.logger.warn (nano::log::type::wallet, "Unable to receive, wallet locked");
}
}
else
@ -880,8 +881,8 @@ std::shared_ptr<nano::block> nano::wallet::receive_action (nano::block_hash cons
}
else
{
wallets.node.logger.try_log (boost::str (boost::format ("Not receiving block %1% due to minimum receive threshold") % send_hash_a.to_string ()));
// Someone sent us something below the threshold of receiving
wallets.node.logger.warn (nano::log::type::wallet, "Not receiving block {} due to minimum receive threshold", send_hash_a.to_string ());
}
if (block != nullptr)
{
@ -1043,7 +1044,10 @@ bool nano::wallet::action_complete (std::shared_ptr<nano::block> const & block_a
auto required_difficulty{ wallets.node.network_params.work.threshold (block_a->work_version (), details_a) };
if (wallets.node.network_params.work.difficulty (*block_a) < required_difficulty)
{
wallets.node.logger.try_log (boost::str (boost::format ("Cached or provided work for block %1% account %2% is invalid, regenerating") % block_a->hash ().to_string () % account_a.to_account ()));
wallets.node.logger.info (nano::log::type::wallet, "Cached or provided work for block {} account {} is invalid, regenerating...",
block_a->hash ().to_string (),
account_a.to_account ());
debug_assert (required_difficulty <= wallets.node.max_work_generate_difficulty (block_a->work_version ()));
error = !wallets.node.work_generate_blocking (*block_a, required_difficulty).is_initialized ();
}
@ -1139,7 +1143,7 @@ void nano::wallet::work_update (store::transaction const & transaction_a, nano::
}
else
{
wallets.node.logger.try_log ("Cached work no longer valid, discarding");
wallets.node.logger.warn (nano::log::type::wallet, "Cached work no longer valid, discarding");
}
}
@ -1168,7 +1172,8 @@ bool nano::wallet::search_receivable (store::transaction const & wallet_transact
auto result (!store.valid_password (wallet_transaction_a));
if (!result)
{
wallets.node.logger.try_log ("Beginning receivable block search");
wallets.node.logger.info (nano::log::type::wallet, "Beginning receivable block search");
for (auto i (store.begin (wallet_transaction_a)), n (store.end ()); i != n; ++i)
{
auto block_transaction (wallets.node.store.tx_begin_read ());
@ -1184,7 +1189,8 @@ bool nano::wallet::search_receivable (store::transaction const & wallet_transact
auto amount (pending.amount.number ());
if (wallets.node.config.receive_minimum.number () <= amount)
{
wallets.node.logger.try_log (boost::str (boost::format ("Found a receivable block %1% for account %2%") % hash.to_string () % pending.source.to_account ()));
wallets.node.logger.info (nano::log::type::wallet, "Found a receivable block {} for account {}", hash.to_string (), pending.source.to_account ());
if (wallets.node.ledger.block_confirmed (block_transaction, hash))
{
auto representative = store.representative (wallet_transaction_a);
@ -1204,11 +1210,12 @@ bool nano::wallet::search_receivable (store::transaction const & wallet_transact
}
}
}
wallets.node.logger.try_log ("Receivable block search phase completed");
wallets.node.logger.info (nano::log::type::wallet, "Receivable block search phase complete");
}
else
{
wallets.node.logger.try_log ("Stopping search, wallet is locked");
wallets.node.logger.warn (nano::log::type::wallet, "Stopping search, wallet is locked");
}
return result;
}
@ -1300,7 +1307,7 @@ void nano::wallet::work_cache_blocking (nano::account const & account_a, nano::r
}
else if (!wallets.node.stopped)
{
wallets.node.logger.try_log (boost::str (boost::format ("Could not precache work for root %1% due to work generation failure") % root_a.to_string ()));
wallets.node.logger.warn (nano::log::type::wallet, "Could not precache work for root {} due to work generation failure", root_a.to_string ());
}
}
}
@ -1556,11 +1563,13 @@ void nano::wallets::foreach_representative (std::function<void (nano::public_key
}
else
{
// TODO: Better logging interval handling
static auto last_log = std::chrono::steady_clock::time_point ();
if (last_log < std::chrono::steady_clock::now () - std::chrono::seconds (60))
{
last_log = std::chrono::steady_clock::now ();
node.logger.always_log (boost::str (boost::format ("Representative locked inside wallet %1%") % i->first.to_string ()));
node.logger.warn (nano::log::type::wallet, "Representative locked inside wallet: {}", i->first.to_string ());
}
}
}

View file

@ -1,6 +1,7 @@
#include <nano/boost/asio/bind_executor.hpp>
#include <nano/boost/asio/dispatch.hpp>
#include <nano/boost/asio/strand.hpp>
#include <nano/lib/logging.hpp>
#include <nano/lib/tlsconfig.hpp>
#include <nano/lib/work.hpp>
#include <nano/node/node_observers.hpp>
@ -14,12 +15,13 @@
#include <algorithm>
#include <chrono>
nano::websocket::confirmation_options::confirmation_options (nano::wallets & wallets_a) :
wallets (wallets_a)
nano::websocket::confirmation_options::confirmation_options (nano::wallets & wallets_a, nano::logger & logger_a) :
wallets (wallets_a),
logger (logger_a)
{
}
nano::websocket::confirmation_options::confirmation_options (boost::property_tree::ptree const & options_a, nano::wallets & wallets_a, nano::logger_mt & logger_a) :
nano::websocket::confirmation_options::confirmation_options (boost::property_tree::ptree const & options_a, nano::wallets & wallets_a, nano::logger & logger_a) :
wallets (wallets_a),
logger (logger_a)
{
@ -62,7 +64,7 @@ nano::websocket::confirmation_options::confirmation_options (boost::property_tre
if (!include_block)
{
logger_a.always_log ("Websocket: Filtering option \"all_local_accounts\" requires that \"include_block\" is set to true to be effective");
logger.warn (nano::log::type::websocket, "Filtering option \"all_local_accounts\" requires that \"include_block\" is set to true to be effective");
}
}
auto accounts_l (options_a.get_child_optional ("accounts"));
@ -79,13 +81,13 @@ nano::websocket::confirmation_options::confirmation_options (boost::property_tre
}
else
{
logger_a.always_log ("Websocket: invalid account provided for filtering blocks: ", account_l.second.data ());
logger.warn (nano::log::type::websocket, "Invalid account provided for filtering blocks: ", account_l.second.data ());
}
}
if (!include_block)
{
logger_a.always_log ("Websocket: Filtering option \"accounts\" requires that \"include_block\" is set to true to be effective");
logger.warn (nano::log::type::websocket, "Filtering option \"accounts\" requires that \"include_block\" is set to true to be effective");
}
}
check_filter_empty ();
@ -158,9 +160,9 @@ bool nano::websocket::confirmation_options::update (boost::property_tree::ptree
this->accounts.erase (encoded_l);
}
}
else if (this->logger.is_initialized ())
else
{
this->logger->always_log ("Websocket: invalid account provided for filtering blocks: ", account_l.second.data ());
logger.warn (nano::log::type::websocket, "Invalid account provided for filtering blocks: ", account_l.second.data ());
}
}
};
@ -186,13 +188,13 @@ bool nano::websocket::confirmation_options::update (boost::property_tree::ptree
void nano::websocket::confirmation_options::check_filter_empty () const
{
// Warn the user if the options resulted in an empty filter
if (logger.is_initialized () && has_account_filtering_options && !all_local_accounts && accounts.empty ())
if (has_account_filtering_options && !all_local_accounts && accounts.empty ())
{
logger->always_log ("Websocket: provided options resulted in an empty block confirmation filter");
logger.warn (nano::log::type::websocket, "Provided options resulted in an empty account confirmation filter");
}
}
nano::websocket::vote_options::vote_options (boost::property_tree::ptree const & options_a, nano::logger_mt & logger_a)
nano::websocket::vote_options::vote_options (boost::property_tree::ptree const & options_a, nano::logger & logger)
{
include_replays = options_a.get<bool> ("include_replays", false);
include_indeterminate = options_a.get<bool> ("include_indeterminate", false);
@ -209,13 +211,13 @@ nano::websocket::vote_options::vote_options (boost::property_tree::ptree const &
}
else
{
logger_a.always_log ("Websocket: invalid account given to filter votes: ", representative_l.second.data ());
logger.warn (nano::log::type::websocket, "Invalid account provided for filtering votes: ", representative_l.second.data ());
}
}
// Warn the user if the option will be ignored
if (representatives.empty ())
{
logger_a.always_log ("Websocket: account filter for votes is empty, no messages will be filtered");
logger.warn (nano::log::type::websocket, "Account filter for votes is empty, no messages will be filtered");
}
}
}
@ -240,15 +242,25 @@ bool nano::websocket::vote_options::should_filter (nano::websocket::message cons
nano::websocket::session::session (nano::websocket::listener & listener_a, socket_type socket_a, boost::asio::ssl::context & ctx_a) :
ws_listener (listener_a), ws (std::move (socket_a), ctx_a)
{
ws_listener.get_logger ().try_log ("Websocket: secure session started");
}
#endif
nano::websocket::session::session (nano::websocket::listener & listener_a, socket_type socket_a) :
ws_listener (listener_a), ws (std::move (socket_a))
nano::websocket::session::session (nano::websocket::listener & listener_a, socket_type socket_a, nano::logger & logger_a) :
ws_listener (listener_a),
ws (std::move (socket_a)),
logger (logger_a)
{
ws_listener.get_logger ().try_log ("Websocket: session started");
{
// Best effort attempt to get endpoint addresses
boost::system::error_code ec;
remote = ws.get_socket ().remote_endpoint (ec);
debug_assert (!ec);
local = ws.get_socket ().local_endpoint (ec);
debug_assert (!ec);
}
logger.info (nano::log::type::websocket, "Session started ({})", nano::util::to_str (remote));
}
nano::websocket::session::~session ()
@ -273,14 +285,14 @@ void nano::websocket::session::handshake ()
}
else
{
this_l->ws_listener.get_logger ().always_log ("Websocket: handshake failed: ", ec.message ());
this_l->logger.error (nano::log::type::websocket, "Handshake failed: {} ({})", ec.message (), nano::util::to_str (this_l->remote));
}
});
}
void nano::websocket::session::close ()
{
ws_listener.get_logger ().try_log ("Websocket: session closing");
logger.info (nano::log::type::websocket, "Session closing ({})", nano::util::to_str (remote));
auto this_l (shared_from_this ());
boost::asio::dispatch (ws.get_strand (),
@ -356,12 +368,12 @@ void nano::websocket::session::read ()
}
catch (boost::property_tree::json_parser::json_parser_error const & ex)
{
this_l->ws_listener.get_logger ().try_log ("Websocket: json parsing failed: ", ex.what ());
this_l->logger.error (nano::log::type::websocket, "JSON parsing failed: {} ({})", ex.what (), nano::util::to_str (this_l->remote));
}
}
else if (ec != boost::asio::error::eof)
{
this_l->ws_listener.get_logger ().try_log ("Websocket: read failed: ", ec.message ());
this_l->logger.error (nano::log::type::websocket, "Read failed: {} ({})", ec.message (), nano::util::to_str (this_l->remote));
}
});
});
@ -483,11 +495,11 @@ void nano::websocket::session::handle_message (boost::property_tree::ptree const
std::unique_ptr<nano::websocket::options> options_l{ nullptr };
if (options_text_l && topic_l == nano::websocket::topic::confirmation)
{
options_l = std::make_unique<nano::websocket::confirmation_options> (options_text_l.get (), ws_listener.get_wallets (), ws_listener.get_logger ());
options_l = std::make_unique<nano::websocket::confirmation_options> (options_text_l.get (), ws_listener.get_wallets (), logger);
}
else if (options_text_l && topic_l == nano::websocket::topic::vote)
{
options_l = std::make_unique<nano::websocket::vote_options> (options_text_l.get (), ws_listener.get_logger ());
options_l = std::make_unique<nano::websocket::vote_options> (options_text_l.get (), logger);
}
else
{
@ -496,13 +508,15 @@ void nano::websocket::session::handle_message (boost::property_tree::ptree const
auto existing (subscriptions.find (topic_l));
if (existing != subscriptions.end ())
{
logger.info (nano::log::type::websocket, "Updated subscription to topic: {} ({})", from_topic (topic_l), nano::util::to_str (remote));
existing->second = std::move (options_l);
ws_listener.get_logger ().always_log ("Websocket: updated subscription to topic: ", from_topic (topic_l));
}
else
{
logger.info (nano::log::type::websocket, "New subscription to topic: {} ({})", from_topic (topic_l), nano::util::to_str (remote));
subscriptions.emplace (topic_l, std::move (options_l));
ws_listener.get_logger ().always_log ("Websocket: new subscription to topic: ", from_topic (topic_l));
ws_listener.increase_subscriber_count (topic_l);
}
action_succeeded = true;
@ -525,7 +539,8 @@ void nano::websocket::session::handle_message (boost::property_tree::ptree const
nano::lock_guard<nano::mutex> lk (subscriptions_mutex);
if (subscriptions.erase (topic_l))
{
ws_listener.get_logger ().always_log ("Websocket: removed subscription to topic: ", from_topic (topic_l));
logger.info (nano::log::type::websocket, "Removed subscription to topic: {} ({})", from_topic (topic_l), nano::util::to_str (remote));
ws_listener.decrease_subscriber_count (topic_l);
}
action_succeeded = true;
@ -559,7 +574,7 @@ void nano::websocket::listener::stop ()
sessions.clear ();
}
nano::websocket::listener::listener (std::shared_ptr<nano::tls_config> const & tls_config_a, nano::logger_mt & logger_a, nano::wallets & wallets_a, boost::asio::io_context & io_ctx_a, boost::asio::ip::tcp::endpoint endpoint_a) :
nano::websocket::listener::listener (std::shared_ptr<nano::tls_config> const & tls_config_a, nano::logger & logger_a, nano::wallets & wallets_a, boost::asio::io_context & io_ctx_a, boost::asio::ip::tcp::endpoint endpoint_a) :
tls_config (tls_config_a),
logger (logger_a),
wallets (wallets_a),
@ -579,7 +594,7 @@ nano::websocket::listener::listener (std::shared_ptr<nano::tls_config> const & t
}
catch (std::exception const & ex)
{
logger.always_log ("Websocket: listen failed: ", ex.what ());
logger.error (nano::log::type::websocket, "Listen failed: {}", ex.what ());
}
}
@ -604,7 +619,7 @@ void nano::websocket::listener::on_accept (boost::system::error_code ec)
{
if (ec)
{
logger.always_log ("Websocket: accept failed: ", ec.message ());
logger.error (nano::log::type::websocket, "Accept failed: {}", ec.message ());
}
else
{
@ -618,7 +633,7 @@ void nano::websocket::listener::on_accept (boost::system::error_code ec)
}
else
{
session = std::make_shared<nano::websocket::session> (*this, std::move (socket));
session = std::make_shared<nano::websocket::session> (*this, std::move (socket), logger);
}
sessions_mutex.lock ();
@ -650,7 +665,7 @@ void nano::websocket::listener::broadcast_confirmation (std::shared_ptr<nano::bl
auto subscription (session_ptr->subscriptions.find (nano::websocket::topic::confirmation));
if (subscription != session_ptr->subscriptions.end ())
{
nano::websocket::confirmation_options default_options (wallets);
nano::websocket::confirmation_options default_options (wallets, logger);
auto conf_options (dynamic_cast<nano::websocket::confirmation_options *> (subscription->second.get ()));
if (conf_options == nullptr)
{
@ -967,7 +982,7 @@ std::string nano::websocket::message::to_string () const
* websocket_server
*/
nano::websocket_server::websocket_server (nano::websocket::config & config_a, nano::node_observers & observers_a, nano::wallets & wallets_a, nano::ledger & ledger_a, boost::asio::io_context & io_ctx_a, nano::logger_mt & logger_a) :
nano::websocket_server::websocket_server (nano::websocket::config & config_a, nano::node_observers & observers_a, nano::wallets & wallets_a, nano::ledger & ledger_a, boost::asio::io_context & io_ctx_a, nano::logger & logger_a) :
config{ config_a },
observers{ observers_a },
wallets{ wallets_a },

View file

@ -21,7 +21,7 @@
namespace nano
{
class wallets;
class logger_mt;
class logger;
class vote;
class election_status;
class telemetry_data;
@ -142,8 +142,8 @@ namespace websocket
class confirmation_options final : public options
{
public:
confirmation_options (nano::wallets & wallets_a);
confirmation_options (boost::property_tree::ptree const & options_a, nano::wallets & wallets_a, nano::logger_mt & logger_a);
confirmation_options (nano::wallets & wallets_a, nano::logger &);
confirmation_options (boost::property_tree::ptree const & options_a, nano::wallets & wallets_a, nano::logger &);
/**
* Checks if a message should be filtered for given block confirmation options.
@ -195,7 +195,8 @@ namespace websocket
void check_filter_empty () const;
nano::wallets & wallets;
boost::optional<nano::logger_mt &> logger;
nano::logger & logger;
bool include_election_info{ false };
bool include_election_info_with_votes{ false };
bool include_sideband_info{ false };
@ -214,7 +215,7 @@ namespace websocket
class vote_options final : public options
{
public:
vote_options (boost::property_tree::ptree const & options_a, nano::logger_mt & logger_a);
vote_options (boost::property_tree::ptree const & options_a, nano::logger &);
/**
* Checks if a message should be filtered for given vote received options.
@ -240,7 +241,7 @@ namespace websocket
explicit session (nano::websocket::listener & listener_a, socket_type socket_a, boost::asio::ssl::context & ctx_a);
#endif
/** Constructor that takes ownership over \p socket_a */
explicit session (nano::websocket::listener & listener_a, socket_type socket_a);
explicit session (nano::websocket::listener & listener_a, socket_type socket_a, nano::logger &);
~session ();
@ -261,11 +262,17 @@ namespace websocket
nano::websocket::listener & ws_listener;
/** Websocket stream, supporting both plain and tls connections */
nano::websocket::stream ws;
nano::logger & logger;
/** Buffer for received messages */
boost::beast::multi_buffer read_buffer;
/** Outgoing messages. The send queue is protected by accessing it only through the strand */
std::deque<message> send_queue;
/** Cache remote & local endpoints to make them available after the socket is closed */
socket_type::endpoint_type remote;
socket_type::endpoint_type local;
/** Hash functor for topic enums */
struct topic_hash
{
@ -291,7 +298,7 @@ namespace websocket
class listener final : public std::enable_shared_from_this<listener>
{
public:
listener (std::shared_ptr<nano::tls_config> const & tls_config_a, nano::logger_mt & logger_a, nano::wallets & wallets_a, boost::asio::io_context & io_ctx_a, boost::asio::ip::tcp::endpoint endpoint_a);
listener (std::shared_ptr<nano::tls_config> const & tls_config_a, nano::logger &, nano::wallets & wallets_a, boost::asio::io_context & io_ctx_a, boost::asio::ip::tcp::endpoint endpoint_a);
/** Start accepting connections */
void run ();
@ -307,11 +314,6 @@ namespace websocket
/** Broadcast \p message to all session subscribing to the message topic. */
void broadcast (nano::websocket::message message_a);
nano::logger_mt & get_logger () const
{
return logger;
}
std::uint16_t listening_port ()
{
return acceptor.local_endpoint ().port ();
@ -346,7 +348,7 @@ namespace websocket
void decrease_subscriber_count (nano::websocket::topic const & topic_a);
std::shared_ptr<nano::tls_config> tls_config;
nano::logger_mt & logger;
nano::logger & logger;
nano::wallets & wallets;
boost::asio::ip::tcp::acceptor acceptor;
socket_type socket;
@ -363,7 +365,7 @@ namespace websocket
class websocket_server
{
public:
websocket_server (nano::websocket::config &, nano::node_observers &, nano::wallets &, nano::ledger &, boost::asio::io_context &, nano::logger_mt &);
websocket_server (nano::websocket::config &, nano::node_observers &, nano::wallets &, nano::ledger &, boost::asio::io_context &, nano::logger &);
void start ();
void stop ();
@ -374,7 +376,7 @@ private: // Dependencies
nano::wallets & wallets;
nano::ledger & ledger;
boost::asio::io_context & io_ctx;
nano::logger_mt & logger;
nano::logger & logger;
public:
// TODO: Encapsulate, this is public just because existing code needs it

View file

@ -67,6 +67,11 @@ public:
return strand;
}
socket_type & get_socket () override
{
return ws.next_layer ();
}
void close (boost::beast::websocket::close_reason const & reason_a, boost::system::error_code & ec_a) override
{
ws.close (reason_a, ec_a);
@ -105,6 +110,11 @@ nano::websocket::stream::stream (socket_type socket_a)
return impl->get_strand ();
}
[[nodiscard]] socket_type & nano::websocket::stream::get_socket ()
{
return impl->get_socket ();
}
void nano::websocket::stream::handshake (std::function<void (boost::system::error_code const & ec)> callback_a)
{
impl->handshake (callback_a);

View file

@ -32,6 +32,7 @@ class websocket_stream_concept
public:
virtual ~websocket_stream_concept () = default;
virtual boost::asio::strand<boost::asio::io_context::executor_type> & get_strand () = 0;
virtual socket_type & get_socket () = 0;
virtual void handshake (std::function<void (boost::system::error_code const & ec)> callback_a) = 0;
virtual void close (boost::beast::websocket::close_reason const & reason_a, boost::system::error_code & ec_a) = 0;
virtual void async_write (nano::shared_const_buffer const & buffer_a, std::function<void (boost::system::error_code, std::size_t)> callback_a) = 0;
@ -51,6 +52,7 @@ public:
stream (socket_type socket_a);
[[nodiscard]] boost::asio::strand<boost::asio::io_context::executor_type> & get_strand () override;
[[nodiscard]] socket_type & get_socket () override;
void handshake (std::function<void (boost::system::error_code const & ec)> callback_a) override;
void close (boost::beast::websocket::close_reason const & reason_a, boost::system::error_code & ec_a) override;
void async_write (nano::shared_const_buffer const & buffer_a, std::function<void (boost::system::error_code, std::size_t)> callback_a) override;

Some files were not shown because too many files have changed in this diff Show more