diff --git a/CMakeLists.txt b/CMakeLists.txt index f90dea20..3a338faf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -77,7 +77,8 @@ if (WIN32) -DWINVER=0x0600 -DWIN32_LEAN_AND_MEAN -DMINIUPNP_STATICLIB - -D_CRT_SECURE_NO_WARNINGS) + -D_CRT_SECURE_NO_WARNINGS + /EHsc) if (${USING_TSAN} OR ${USING_ASAN} OR ${USING_ASAN_INT}) message (WARNING "Cannot use TSAN or ASAN on Windows, sanitizers ignored") diff --git a/ci/build-travis.sh b/ci/build-travis.sh index d3691ef9..dc492758 100755 --- a/ci/build-travis.sh +++ b/ci/build-travis.sh @@ -15,7 +15,7 @@ if [[ $(grep -rl --exclude="*asio.hpp" "asio::async_write" ./nano) ]]; then fi # prevent unsolicited use of std::lock_guard & std::unique_lock outside of allowed areas -if [[ $(grep -rl --exclude={"*random_pool.cpp","*random_pool.hpp","*locks.hpp","*locks.cpp"} "std::unique_lock\|std::lock_guard\|std::condition_variable" ./nano) ]]; then +if [[ $(grep -rl --exclude={"*random_pool.cpp","*random_pool.hpp","*random_pool_shuffle.hpp","*locks.hpp","*locks.cpp"} "std::unique_lock\|std::lock_guard\|std::condition_variable" ./nano) ]]; then echo "using std::unique_lock, std::lock_guard or std::condition_variable is not permitted (except in nano/lib/locks.hpp and non-nano dependent libraries). Use the nano::* versions instead" exit 1 fi diff --git a/nano/boost/asio.hpp b/nano/boost/asio.hpp deleted file mode 100644 index fc9ba6cd..00000000 --- a/nano/boost/asio.hpp +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#ifdef _WIN32 -#pragma warning(push) -#pragma warning(disable : 4191) -#pragma warning(disable : 4242) -#endif - -#include - -#ifdef _WIN32 -#pragma warning(pop) -#endif diff --git a/nano/boost/asio/basic_stream_socket.hpp b/nano/boost/asio/basic_stream_socket.hpp new file mode 100644 index 00000000..51cc6dee --- /dev/null +++ b/nano/boost/asio/basic_stream_socket.hpp @@ -0,0 +1,7 @@ +#pragma once + +#include + +DISABLE_ASIO_WARNINGS +#include +REENABLE_WARNINGS diff --git a/nano/boost/asio/bind_executor.hpp b/nano/boost/asio/bind_executor.hpp new file mode 100644 index 00000000..0dd56f67 --- /dev/null +++ b/nano/boost/asio/bind_executor.hpp @@ -0,0 +1,7 @@ +#pragma once + +#include + +DISABLE_ASIO_WARNINGS +#include +REENABLE_WARNINGS diff --git a/nano/boost/asio/buffer.hpp b/nano/boost/asio/buffer.hpp new file mode 100644 index 00000000..3d6809a6 --- /dev/null +++ b/nano/boost/asio/buffer.hpp @@ -0,0 +1,7 @@ +#pragma once + +#include + +DISABLE_ASIO_WARNINGS +#include +REENABLE_WARNINGS diff --git a/nano/boost/asio/connect.hpp b/nano/boost/asio/connect.hpp new file mode 100644 index 00000000..03933794 --- /dev/null +++ b/nano/boost/asio/connect.hpp @@ -0,0 +1,7 @@ +#pragma once + +#include + +DISABLE_ASIO_WARNINGS +#include +REENABLE_WARNINGS diff --git a/nano/boost/asio/deadline_timer.hpp b/nano/boost/asio/deadline_timer.hpp new file mode 100644 index 00000000..8112d4b3 --- /dev/null +++ b/nano/boost/asio/deadline_timer.hpp @@ -0,0 +1,7 @@ +#pragma once + +#include + +DISABLE_ASIO_WARNINGS +#include +REENABLE_WARNINGS diff --git a/nano/boost/asio/dispatch.hpp b/nano/boost/asio/dispatch.hpp new file mode 100644 index 00000000..3336b7d0 --- /dev/null +++ b/nano/boost/asio/dispatch.hpp @@ -0,0 +1,7 @@ +#pragma once + +#include + +DISABLE_ASIO_WARNINGS +#include +REENABLE_WARNINGS diff --git a/nano/boost/asio/executor_work_guard.hpp b/nano/boost/asio/executor_work_guard.hpp new file mode 100644 index 00000000..261693e6 --- /dev/null +++ b/nano/boost/asio/executor_work_guard.hpp @@ -0,0 +1,7 @@ +#pragma once + +#include + +DISABLE_ASIO_WARNINGS +#include +REENABLE_WARNINGS diff --git a/nano/boost/asio/io_context.hpp b/nano/boost/asio/io_context.hpp new file mode 100644 index 00000000..85ce3156 --- /dev/null +++ b/nano/boost/asio/io_context.hpp @@ -0,0 +1,7 @@ +#pragma once + +#include + +DISABLE_ASIO_WARNINGS +#include +REENABLE_WARNINGS diff --git a/nano/boost/asio/ip/address.hpp b/nano/boost/asio/ip/address.hpp new file mode 100644 index 00000000..3fed1bf8 --- /dev/null +++ b/nano/boost/asio/ip/address.hpp @@ -0,0 +1,7 @@ +#pragma once + +#include + +DISABLE_ASIO_WARNINGS +#include +REENABLE_WARNINGS diff --git a/nano/boost/asio/ip/address_v6.hpp b/nano/boost/asio/ip/address_v6.hpp new file mode 100644 index 00000000..6b1cd46a --- /dev/null +++ b/nano/boost/asio/ip/address_v6.hpp @@ -0,0 +1,7 @@ +#pragma once + +#include + +DISABLE_ASIO_WARNINGS +#include +REENABLE_WARNINGS diff --git a/nano/boost/asio/ip/tcp.hpp b/nano/boost/asio/ip/tcp.hpp new file mode 100644 index 00000000..e1f2d161 --- /dev/null +++ b/nano/boost/asio/ip/tcp.hpp @@ -0,0 +1,7 @@ +#pragma once + +#include + +DISABLE_ASIO_WARNINGS +#include +REENABLE_WARNINGS diff --git a/nano/boost/asio/ip/udp.hpp b/nano/boost/asio/ip/udp.hpp new file mode 100644 index 00000000..1efc97c5 --- /dev/null +++ b/nano/boost/asio/ip/udp.hpp @@ -0,0 +1,7 @@ +#pragma once + +#include + +DISABLE_ASIO_WARNINGS +#include +REENABLE_WARNINGS diff --git a/nano/boost/asio/local/stream_protocol.hpp b/nano/boost/asio/local/stream_protocol.hpp new file mode 100644 index 00000000..31ca4ebe --- /dev/null +++ b/nano/boost/asio/local/stream_protocol.hpp @@ -0,0 +1,7 @@ +#pragma once + +#include + +DISABLE_ASIO_WARNINGS +#include +REENABLE_WARNINGS diff --git a/nano/boost/asio/post.hpp b/nano/boost/asio/post.hpp new file mode 100644 index 00000000..80af5ef5 --- /dev/null +++ b/nano/boost/asio/post.hpp @@ -0,0 +1,7 @@ +#pragma once + +#include + +DISABLE_ASIO_WARNINGS +#include +REENABLE_WARNINGS diff --git a/nano/boost/asio/read.hpp b/nano/boost/asio/read.hpp new file mode 100644 index 00000000..e029b904 --- /dev/null +++ b/nano/boost/asio/read.hpp @@ -0,0 +1,7 @@ +#pragma once + +#include + +DISABLE_ASIO_WARNINGS +#include +REENABLE_WARNINGS diff --git a/nano/boost/asio/strand.hpp b/nano/boost/asio/strand.hpp new file mode 100644 index 00000000..12ca0200 --- /dev/null +++ b/nano/boost/asio/strand.hpp @@ -0,0 +1,7 @@ +#pragma once + +#include + +DISABLE_ASIO_WARNINGS +#include +REENABLE_WARNINGS diff --git a/nano/boost/asio/thread_pool.hpp b/nano/boost/asio/thread_pool.hpp new file mode 100644 index 00000000..0b808cb3 --- /dev/null +++ b/nano/boost/asio/thread_pool.hpp @@ -0,0 +1,7 @@ +#pragma once + +#include + +DISABLE_ASIO_WARNINGS +#include +REENABLE_WARNINGS diff --git a/nano/boost/asio/write.hpp b/nano/boost/asio/write.hpp new file mode 100644 index 00000000..48a83ffc --- /dev/null +++ b/nano/boost/asio/write.hpp @@ -0,0 +1,7 @@ +#pragma once + +#include + +DISABLE_ASIO_WARNINGS +#include +REENABLE_WARNINGS diff --git a/nano/boost/beast.hpp b/nano/boost/beast.hpp deleted file mode 100644 index 462b1558..00000000 --- a/nano/boost/beast.hpp +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#ifdef _WIN32 -#pragma warning(push) -#pragma warning(disable : 4191) -#pragma warning(disable : 4242) -#endif - -#include - -#ifdef _WIN32 -#pragma warning(pop) -#endif diff --git a/nano/boost/beast/core.hpp b/nano/boost/beast/core.hpp new file mode 100644 index 00000000..8bee46e2 --- /dev/null +++ b/nano/boost/beast/core.hpp @@ -0,0 +1,7 @@ +#pragma once + +#include + +DISABLE_BEAST_WARNINGS +#include +REENABLE_WARNINGS diff --git a/nano/boost/beast/core/flat_buffer.hpp b/nano/boost/beast/core/flat_buffer.hpp new file mode 100644 index 00000000..1ec8513f --- /dev/null +++ b/nano/boost/beast/core/flat_buffer.hpp @@ -0,0 +1,7 @@ +#pragma once + +#include + +DISABLE_BEAST_WARNINGS +#include +REENABLE_WARNINGS diff --git a/nano/boost/beast/http.hpp b/nano/boost/beast/http.hpp new file mode 100644 index 00000000..fdb5413c --- /dev/null +++ b/nano/boost/beast/http.hpp @@ -0,0 +1,7 @@ +#pragma once + +#include + +DISABLE_BEAST_WARNINGS +#include +REENABLE_WARNINGS diff --git a/nano/boost/beast/http/message.hpp b/nano/boost/beast/http/message.hpp new file mode 100644 index 00000000..ce2a3363 --- /dev/null +++ b/nano/boost/beast/http/message.hpp @@ -0,0 +1,7 @@ +#pragma once + +#include + +DISABLE_BEAST_WARNINGS +#include +REENABLE_WARNINGS diff --git a/nano/boost/beast/http/string_body.hpp b/nano/boost/beast/http/string_body.hpp new file mode 100644 index 00000000..a9da9dcb --- /dev/null +++ b/nano/boost/beast/http/string_body.hpp @@ -0,0 +1,7 @@ +#pragma once + +#include + +DISABLE_BEAST_WARNINGS +#include +REENABLE_WARNINGS diff --git a/nano/boost/beast/version.hpp b/nano/boost/beast/version.hpp new file mode 100644 index 00000000..eb55c0c3 --- /dev/null +++ b/nano/boost/beast/version.hpp @@ -0,0 +1,7 @@ +#pragma once + +#include + +DISABLE_BEAST_WARNINGS +#include +REENABLE_WARNINGS diff --git a/nano/boost/beast/websocket.hpp b/nano/boost/beast/websocket.hpp new file mode 100644 index 00000000..cbd0fe92 --- /dev/null +++ b/nano/boost/beast/websocket.hpp @@ -0,0 +1,7 @@ +#pragma once + +#include + +DISABLE_BEAST_WARNINGS +#include +REENABLE_WARNINGS diff --git a/nano/boost/private/macro_warnings.hpp b/nano/boost/private/macro_warnings.hpp new file mode 100644 index 00000000..85fe8d80 --- /dev/null +++ b/nano/boost/private/macro_warnings.hpp @@ -0,0 +1,30 @@ +#pragma once + +#ifdef _WIN32 +#define DISABLE_ASIO_WARNINGS \ + __pragma (warning (push)) \ + __pragma (warning (disable : 4191)) \ + __pragma (warning (disable : 4242)) + +#else +#define DISABLE_ASIO_WARNINGS +#endif + +#ifdef _WIN32 +#define REENABLE_WARNINGS \ + __pragma (warning (pop)) +#else +#define REENABLE_WARNINGS +#endif + +#define DISABLE_BEAST_WARNINGS DISABLE_ASIO_WARNINGS + +#ifdef _WIN32 +#define DISABLE_PROCESS_WARNINGS \ + __pragma (warning (push)) \ + __pragma (warning (disable : 4191)) \ + __pragma (warning (disable : 4242)) \ + __pragma (warning (disable : 4244)) +#else +#define DISABLE_PROCESS_WARNINGS +#endif diff --git a/nano/boost/process.hpp b/nano/boost/process.hpp deleted file mode 100644 index 6bd9b6a1..00000000 --- a/nano/boost/process.hpp +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once - -#ifndef BOOST_PROCESS_SUPPORTED -#error BOOST_PROCESS_SUPPORTED must be set, check configuration -#endif - -#if BOOST_PROCESS_SUPPORTED - -#ifdef _WIN32 -#pragma warning(push) -#pragma warning(disable : 4191) -#pragma warning(disable : 4242) -#pragma warning(disable : 4244) -#endif - -#include - -#ifdef _WIN32 -#pragma warning(pop) -#endif - -#endif diff --git a/nano/boost/process/child.hpp b/nano/boost/process/child.hpp new file mode 100644 index 00000000..f04947ba --- /dev/null +++ b/nano/boost/process/child.hpp @@ -0,0 +1,7 @@ +#pragma once + +#include + +DISABLE_BEAST_WARNINGS +#include +REENABLE_WARNINGS diff --git a/nano/core_test/active_transactions.cpp b/nano/core_test/active_transactions.cpp index 29f51569..02eed758 100644 --- a/nano/core_test/active_transactions.cpp +++ b/nano/core_test/active_transactions.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include @@ -544,7 +545,6 @@ TEST (active_transactions, update_difficulty) ASSERT_FALSE (ec); auto modify_election = [&node1](auto block) { - auto root_l (block->root ()); auto hash (block->hash ()); nano::lock_guard active_guard (node1.active.mutex); auto existing (node1.active.roots.find (block->qualified_root ())); diff --git a/nano/core_test/block.cpp b/nano/core_test/block.cpp index 03aaaa1b..e4359503 100644 --- a/nano/core_test/block.cpp +++ b/nano/core_test/block.cpp @@ -1,13 +1,11 @@ #include #include -#include +#include #include #include -#include - #include TEST (ed25519, signing) diff --git a/nano/core_test/block_store.cpp b/nano/core_test/block_store.cpp index dd67a9cf..98005ce5 100644 --- a/nano/core_test/block_store.cpp +++ b/nano/core_test/block_store.cpp @@ -1,17 +1,26 @@ #include #include +#include #include +#include #include -#include +#include +#include #include +#include + #if NANO_ROCKSDB #include #endif +#include +#include + #include #include +#include #include @@ -1503,7 +1512,7 @@ TEST (block_store, peers) TEST (block_store, endpoint_key_byte_order) { - boost::asio::ip::address_v6 address (boost::asio::ip::address_v6::from_string ("::ffff:127.0.0.1")); + boost::asio::ip::address_v6 address (boost::asio::ip::make_address_v6 ("::ffff:127.0.0.1")); uint16_t port = 100; nano::endpoint_key endpoint_key (address.to_bytes (), port); diff --git a/nano/core_test/bootstrap.cpp b/nano/core_test/bootstrap.cpp index 25bb35bc..e248a176 100644 --- a/nano/core_test/bootstrap.cpp +++ b/nano/core_test/bootstrap.cpp @@ -1,4 +1,5 @@ #include +#include #include #include diff --git a/nano/core_test/confirmation_height.cpp b/nano/core_test/confirmation_height.cpp index 4ac7c398..c610b877 100644 --- a/nano/core_test/confirmation_height.cpp +++ b/nano/core_test/confirmation_height.cpp @@ -1,8 +1,11 @@ #include +#include #include #include +#include + using namespace std::chrono_literals; namespace @@ -979,7 +982,6 @@ TEST (confirmation_height, callback_confirmed_history) nano::block_hash latest (node->latest (nano::test_genesis_key.pub)); nano::keypair key1; - auto & store = node->store; auto send = std::make_shared (latest, key1.pub, nano::genesis_amount - nano::Gxrb_ratio, nano::test_genesis_key.prv, nano::test_genesis_key.pub, *system.work.generate (latest)); { auto transaction = node->store.tx_begin_write (); @@ -1058,7 +1060,6 @@ TEST (confirmation_height, dependent_election) nano::block_hash latest (node->latest (nano::test_genesis_key.pub)); nano::keypair key1; - auto & store = node->store; auto send = std::make_shared (latest, key1.pub, nano::genesis_amount - nano::Gxrb_ratio, nano::test_genesis_key.prv, nano::test_genesis_key.pub, *system.work.generate (latest)); auto send1 = std::make_shared (send->hash (), key1.pub, nano::genesis_amount - nano::Gxrb_ratio * 2, nano::test_genesis_key.prv, nano::test_genesis_key.pub, *system.work.generate (send->hash ())); auto send2 = std::make_shared (send1->hash (), key1.pub, nano::genesis_amount - nano::Gxrb_ratio * 3, nano::test_genesis_key.prv, nano::test_genesis_key.pub, *system.work.generate (send1->hash ())); @@ -1122,7 +1123,6 @@ TEST (confirmation_height, dependent_election_after_already_cemented) nano::block_hash latest (node->latest (nano::test_genesis_key.pub)); nano::keypair key1; - auto & store = node->store; auto send = std::make_shared (latest, key1.pub, nano::genesis_amount - nano::Gxrb_ratio, nano::test_genesis_key.prv, nano::test_genesis_key.pub, *system.work.generate (latest)); auto send1 = std::make_shared (send->hash (), key1.pub, nano::genesis_amount - nano::Gxrb_ratio * 2, nano::test_genesis_key.prv, nano::test_genesis_key.pub, *system.work.generate (send->hash ())); diff --git a/nano/core_test/conflicts.cpp b/nano/core_test/conflicts.cpp index d55cd587..41ca3f10 100644 --- a/nano/core_test/conflicts.cpp +++ b/nano/core_test/conflicts.cpp @@ -1,8 +1,11 @@ #include +#include #include #include +#include + using namespace std::chrono_literals; TEST (conflicts, start_stop) diff --git a/nano/core_test/core_test_main.cc b/nano/core_test/core_test_main.cc index d9c606b4..291bb63e 100644 --- a/nano/core_test/core_test_main.cc +++ b/nano/core_test/core_test_main.cc @@ -3,10 +3,13 @@ #include #include +#include + namespace nano { void cleanup_test_directories_on_exit (); void force_nano_test_network (); +boost::filesystem::path unique_path (); } GTEST_API_ int main (int argc, char ** argv) diff --git a/nano/core_test/ledger.cpp b/nano/core_test/ledger.cpp index 7dff16f3..2bbe6b93 100644 --- a/nano/core_test/ledger.cpp +++ b/nano/core_test/ledger.cpp @@ -1,9 +1,9 @@ #include #include +#include +#include #include -#include -#include #include using namespace std::chrono_literals; diff --git a/nano/core_test/locks.cpp b/nano/core_test/locks.cpp index b52b66b4..ad4a2ae7 100644 --- a/nano/core_test/locks.cpp +++ b/nano/core_test/locks.cpp @@ -3,6 +3,7 @@ #include +#include #include #if NANO_TIMED_LOCKS > 0 diff --git a/nano/core_test/logger.cpp b/nano/core_test/logger.cpp index ba390f12..e5172d25 100644 --- a/nano/core_test/logger.cpp +++ b/nano/core_test/logger.cpp @@ -1,13 +1,14 @@ #include +#include +#include #include #include #include -#include - #include #include +#include using namespace std::chrono_literals; diff --git a/nano/core_test/message.cpp b/nano/core_test/message.cpp index 33c24fcd..2eff4917 100644 --- a/nano/core_test/message.cpp +++ b/nano/core_test/message.cpp @@ -1,7 +1,10 @@ #include +#include #include +#include + TEST (message, keepalive_serialization) { nano::keepalive request1; diff --git a/nano/core_test/network.cpp b/nano/core_test/network.cpp index 4e985e6f..eddab44f 100644 --- a/nano/core_test/network.cpp +++ b/nano/core_test/network.cpp @@ -465,7 +465,7 @@ TEST (parse_endpoint, no_colon) TEST (network, ipv6) { - boost::asio::ip::address_v6 address (boost::asio::ip::address_v6::from_string ("::ffff:127.0.0.1")); + boost::asio::ip::address_v6 address (boost::asio::ip::make_address_v6 ("::ffff:127.0.0.1")); ASSERT_TRUE (address.is_v4_mapped ()); nano::endpoint endpoint1 (address, 16384); std::vector bytes1; @@ -557,12 +557,12 @@ TEST (network, reserved_address) { nano::system system (1); // 0 port test - ASSERT_TRUE (nano::transport::reserved_address (nano::endpoint (boost::asio::ip::address_v6::from_string ("2001::"), 0))); + ASSERT_TRUE (nano::transport::reserved_address (nano::endpoint (boost::asio::ip::make_address_v6 ("2001::"), 0))); // Valid address test - ASSERT_FALSE (nano::transport::reserved_address (nano::endpoint (boost::asio::ip::address_v6::from_string ("2001::"), 1))); - nano::endpoint loopback (boost::asio::ip::address_v6::from_string ("::1"), 1); + ASSERT_FALSE (nano::transport::reserved_address (nano::endpoint (boost::asio::ip::make_address_v6 ("2001::"), 1))); + nano::endpoint loopback (boost::asio::ip::make_address_v6 ("::1"), 1); ASSERT_FALSE (nano::transport::reserved_address (loopback)); - nano::endpoint private_network_peer (boost::asio::ip::address_v6::from_string ("::ffff:10.0.0.0"), 1); + nano::endpoint private_network_peer (boost::asio::ip::make_address_v6 ("::ffff:10.0.0.0"), 1); ASSERT_TRUE (nano::transport::reserved_address (private_network_peer, false)); ASSERT_FALSE (nano::transport::reserved_address (private_network_peer, true)); } diff --git a/nano/core_test/node.cpp b/nano/core_test/node.cpp index 31d921a0..60160955 100644 --- a/nano/core_test/node.cpp +++ b/nano/core_test/node.cpp @@ -1,13 +1,14 @@ #include #include +#include #include #include -#include #include +#include #include -#include +#include #include @@ -798,7 +799,7 @@ TEST (node_config, v17_values) ASSERT_FALSE (upgraded); ASSERT_EQ (config.tcp_io_timeout.count (), 1); ASSERT_EQ (config.pow_sleep_interval.count (), 0); - ASSERT_EQ (config.external_address, boost::asio::ip::address_v6::from_string ("::1")); + ASSERT_EQ (config.external_address, "::1"); ASSERT_EQ (config.external_port, 0); ASSERT_EQ (config.tcp_incoming_connections_max, 1); ASSERT_FALSE (config.diagnostics_config.txn_tracking.enable); @@ -838,7 +839,7 @@ TEST (node_config, v17_values) ASSERT_FALSE (upgraded); ASSERT_EQ (config.tcp_io_timeout.count (), std::numeric_limits::max () - 100); ASSERT_EQ (config.pow_sleep_interval.count (), std::numeric_limits::max () - 100); - ASSERT_EQ (config.external_address, boost::asio::ip::address_v6::from_string ("::ffff:192.168.1.1")); + ASSERT_EQ (config.external_address, "::ffff:192.168.1.1"); ASSERT_EQ (config.external_port, std::numeric_limits::max () - 1); ASSERT_EQ (config.tcp_incoming_connections_max, std::numeric_limits::max ()); ASSERT_EQ (config.vote_generator_delay.count (), std::numeric_limits::max () - 100); diff --git a/nano/core_test/processor_service.cpp b/nano/core_test/processor_service.cpp index 81aec8ad..5265a10f 100644 --- a/nano/core_test/processor_service.cpp +++ b/nano/core_test/processor_service.cpp @@ -1,12 +1,17 @@ +#include #include -#include +#include +#include +#include +#include +#include +#include #include #include #include #include -#include TEST (processor_service, bad_send_signature) { diff --git a/nano/core_test/signing.cpp b/nano/core_test/signing.cpp index c485b9b8..44c0f587 100644 --- a/nano/core_test/signing.cpp +++ b/nano/core_test/signing.cpp @@ -1,4 +1,5 @@ -#include +#include +#include #include diff --git a/nano/core_test/socket.cpp b/nano/core_test/socket.cpp index 14907b31..4d6bce08 100644 --- a/nano/core_test/socket.cpp +++ b/nano/core_test/socket.cpp @@ -1,11 +1,10 @@ #include +#include #include #include #include -#include - using namespace std::chrono_literals; TEST (socket, concurrent_writes) diff --git a/nano/core_test/testutil.hpp b/nano/core_test/testutil.hpp index e9d1387f..afd7849a 100644 --- a/nano/core_test/testutil.hpp +++ b/nano/core_test/testutil.hpp @@ -1,10 +1,10 @@ #pragma once +#include #include -#include #include -#include +#include #include #include @@ -51,7 +51,7 @@ class stringstream_mt_sink : public boost::iostreams::sink { public: stringstream_mt_sink () = default; - stringstream_mt_sink (const stringstream_mt_sink & sink) + stringstream_mt_sink (stringstream_mt_sink const & sink) { nano::lock_guard guard (mutex); ss << sink.ss.str (); diff --git a/nano/core_test/utility.cpp b/nano/core_test/utility.cpp index 2304ceb5..8e77280d 100644 --- a/nano/core_test/utility.cpp +++ b/nano/core_test/utility.cpp @@ -1,9 +1,12 @@ #include #include +#include #include #include +#include + namespace { std::atomic passed_sleep{ false }; diff --git a/nano/core_test/versioning.cpp b/nano/core_test/versioning.cpp index 8503ca11..0f1bddd0 100644 --- a/nano/core_test/versioning.cpp +++ b/nano/core_test/versioning.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include diff --git a/nano/core_test/wallet.cpp b/nano/core_test/wallet.cpp index b16b3e96..e343675c 100644 --- a/nano/core_test/wallet.cpp +++ b/nano/core_test/wallet.cpp @@ -1,11 +1,12 @@ #include #include +#include #include #include #include -#include +#include using namespace std::chrono_literals; unsigned constexpr nano::wallet_store::version_current; diff --git a/nano/core_test/wallets.cpp b/nano/core_test/wallets.cpp index 0a0768e7..837f23e0 100644 --- a/nano/core_test/wallets.cpp +++ b/nano/core_test/wallets.cpp @@ -5,8 +5,6 @@ #include -#include - using namespace std::chrono_literals; TEST (wallets, open_create) diff --git a/nano/core_test/websocket.cpp b/nano/core_test/websocket.cpp index 0ed7e002..199547d8 100644 --- a/nano/core_test/websocket.cpp +++ b/nano/core_test/websocket.cpp @@ -1,7 +1,8 @@ -#include -#include +#include +#include +#include +#include #include -#include #include #include @@ -10,9 +11,7 @@ #include #include -#include #include -#include #include #include #include diff --git a/nano/core_test/work_pool.cpp b/nano/core_test/work_pool.cpp index f30bd39c..2cd9a62c 100644 --- a/nano/core_test/work_pool.cpp +++ b/nano/core_test/work_pool.cpp @@ -1,11 +1,19 @@ #include +#include #include +#include #include -#include -#include +#include +#include +#include +#include +#include +#include #include +#include + TEST (work, one) { nano::network_constants network_constants; diff --git a/nano/crypto_lib/CMakeLists.txt b/nano/crypto_lib/CMakeLists.txt index c2b509ae..23b07663 100644 --- a/nano/crypto_lib/CMakeLists.txt +++ b/nano/crypto_lib/CMakeLists.txt @@ -1,7 +1,8 @@ add_library (crypto_lib interface.cpp + random_pool.hpp random_pool.cpp - random_pool.hpp) + random_pool_shuffle.hpp) target_link_libraries (crypto_lib blake2 diff --git a/nano/crypto_lib/random_pool.cpp b/nano/crypto_lib/random_pool.cpp index 984f51f6..baaa7e78 100644 --- a/nano/crypto_lib/random_pool.cpp +++ b/nano/crypto_lib/random_pool.cpp @@ -1,22 +1,32 @@ #include +#include + std::mutex nano::random_pool::mutex; -CryptoPP::AutoSeededRandomPool nano::random_pool::pool; void nano::random_pool::generate_block (unsigned char * output, size_t size) { + auto & pool = get_pool (); std::lock_guard guard (mutex); pool.GenerateBlock (output, size); } unsigned nano::random_pool::generate_word32 (unsigned min, unsigned max) { + auto & pool = get_pool (); std::lock_guard guard (mutex); return pool.GenerateWord32 (min, max); } unsigned char nano::random_pool::generate_byte () { + auto & pool = get_pool (); std::lock_guard guard (mutex); return pool.GenerateByte (); } + +CryptoPP::AutoSeededRandomPool & nano::random_pool::get_pool () +{ + static CryptoPP::AutoSeededRandomPool pool; + return pool; +} diff --git a/nano/crypto_lib/random_pool.hpp b/nano/crypto_lib/random_pool.hpp index 8789d236..2afd591f 100644 --- a/nano/crypto_lib/random_pool.hpp +++ b/nano/crypto_lib/random_pool.hpp @@ -1,9 +1,12 @@ #pragma once -#include - #include +namespace CryptoPP +{ +class AutoSeededRandomPool; +} + namespace nano { /** While this uses CryptoPP do not call any of these functions from global scope, as they depend on global variables inside the CryptoPP library which may not have been initialized yet due to an undefined order for globals in different translation units. To make sure this is not an issue, there should be no ASAN warnings at startup on Mac/Clang in the CryptoPP files. */ @@ -14,19 +17,15 @@ public: static unsigned generate_word32 (unsigned min, unsigned max); static unsigned char generate_byte (); - template - static void shuffle (Iter begin, Iter end) - { - std::lock_guard guard (mutex); - pool.Shuffle (begin, end); - } - random_pool () = delete; random_pool (random_pool const &) = delete; random_pool & operator= (random_pool const &) = delete; private: static std::mutex mutex; - static CryptoPP::AutoSeededRandomPool pool; + static CryptoPP::AutoSeededRandomPool & get_pool (); + + template + friend void random_pool_shuffle (Iter begin, Iter end); }; } \ No newline at end of file diff --git a/nano/crypto_lib/random_pool_shuffle.hpp b/nano/crypto_lib/random_pool_shuffle.hpp new file mode 100644 index 00000000..848127ef --- /dev/null +++ b/nano/crypto_lib/random_pool_shuffle.hpp @@ -0,0 +1,15 @@ +#pragma once + +#include + +#include + +namespace nano +{ +template +void random_pool_shuffle (Iter begin, Iter end) +{ + std::lock_guard guard (random_pool::mutex); + random_pool::get_pool ().Shuffle (begin, end); +} +} diff --git a/nano/lib/CMakeLists.txt b/nano/lib/CMakeLists.txt index 71f0d699..faef2b19 100644 --- a/nano/lib/CMakeLists.txt +++ b/nano/lib/CMakeLists.txt @@ -33,6 +33,7 @@ add_library (nano_lib ipc_client.cpp json_error_response.hpp jsonconfig.hpp + jsonconfig.cpp locks.hpp locks.cpp logger_mt.hpp @@ -49,14 +50,20 @@ add_library (nano_lib rpcconfig.cpp stats.hpp stats.cpp + threading.hpp + threading.cpp timer.hpp + timer.cpp tomlconfig.hpp + tomlconfig.cpp utility.hpp utility.cpp walletconfig.hpp walletconfig.cpp work.hpp - work.cpp) + work.cpp + worker.hpp + worker.cpp) target_link_libraries (nano_lib ed25519 diff --git a/nano/lib/alarm.cpp b/nano/lib/alarm.cpp index 18ffd09e..e8f9c5df 100644 --- a/nano/lib/alarm.cpp +++ b/nano/lib/alarm.cpp @@ -1,5 +1,5 @@ #include -#include +#include bool nano::operation::operator> (nano::operation const & other_a) const { diff --git a/nano/lib/alarm.hpp b/nano/lib/alarm.hpp index 3e289442..caaf84a8 100644 --- a/nano/lib/alarm.hpp +++ b/nano/lib/alarm.hpp @@ -1,14 +1,21 @@ #pragma once +#include #include -#include -#include - #include #include #include #include +#include + +namespace boost +{ +namespace asio +{ + class io_context; +} +} namespace nano { @@ -33,7 +40,7 @@ public: std::mutex mutex; nano::condition_variable condition; std::priority_queue, std::greater> operations; - boost::thread thread; + std::thread thread; }; class seq_con_info_component; std::unique_ptr collect_seq_con_info (alarm & alarm, const std::string & name); diff --git a/nano/lib/asio.hpp b/nano/lib/asio.hpp index f25c2d3d..ee939dd3 100644 --- a/nano/lib/asio.hpp +++ b/nano/lib/asio.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include namespace nano { diff --git a/nano/lib/blockbuilders.cpp b/nano/lib/blockbuilders.cpp index 61ef2562..92935546 100644 --- a/nano/lib/blockbuilders.cpp +++ b/nano/lib/blockbuilders.cpp @@ -650,3 +650,64 @@ nano::receive_block_builder & nano::receive_block_builder::source_hex (std::stri build_state |= build_flags::link_present; return *this; } + +template +std::unique_ptr nano::abstract_builder::build () +{ + if (!ec) + { + static_cast (this)->validate (); + } + assert (!ec); + return std::move (block); +} + +template +std::unique_ptr nano::abstract_builder::build (std::error_code & ec) +{ + if (!this->ec) + { + static_cast (this)->validate (); + } + ec = this->ec; + return std::move (block); +} + +template +nano::abstract_builder & nano::abstract_builder::work (uint64_t work) +{ + block->work = work; + build_state |= build_flags::work_present; + return *this; +} + +template +nano::abstract_builder & nano::abstract_builder::sign (nano::raw_key const & private_key, nano::public_key const & public_key) +{ + block->signature = nano::sign_message (private_key, public_key, block->hash ()); + build_state |= build_flags::signature_present; + return *this; +} + +template +nano::abstract_builder & nano::abstract_builder::sign_zero () +{ + block->signature.clear (); + build_state |= build_flags::signature_present; + return *this; +} + +template +void nano::abstract_builder::construct_block () +{ + block = std::make_unique (); + ec.clear (); + build_state = 0; +} + +// Explicit instantiations +template class nano::abstract_builder; +template class nano::abstract_builder; +template class nano::abstract_builder; +template class nano::abstract_builder; +template class nano::abstract_builder; diff --git a/nano/lib/blockbuilders.hpp b/nano/lib/blockbuilders.hpp index 246bea6b..d57975f7 100644 --- a/nano/lib/blockbuilders.hpp +++ b/nano/lib/blockbuilders.hpp @@ -1,7 +1,6 @@ #pragma once #include -#include #include @@ -46,63 +45,21 @@ class abstract_builder { public: /** Returns the built block as a unique_ptr */ - inline std::unique_ptr build () - { - if (!ec) - { - static_cast (this)->validate (); - } - assert (!ec); - return std::move (block); - } - + std::unique_ptr build (); /** Returns the built block as a unique_ptr. Any errors are placed in \p ec */ - inline std::unique_ptr build (std::error_code & ec) - { - if (!this->ec) - { - static_cast (this)->validate (); - } - ec = this->ec; - return std::move (block); - } - + std::unique_ptr build (std::error_code & ec); /** Set work value */ - inline abstract_builder & work (uint64_t work) - { - block->work = work; - build_state |= build_flags::work_present; - return *this; - } - + abstract_builder & work (uint64_t work); /** Sign the block using the \p private_key and \p public_key */ - inline abstract_builder & sign (nano::raw_key const & private_key, nano::public_key const & public_key) - { - block->signature = nano::sign_message (private_key, public_key, block->hash ()); - build_state |= build_flags::signature_present; - return *this; - } - + abstract_builder & sign (nano::raw_key const & private_key, nano::public_key const & public_key); /** Set signature to zero to pass build() validation, allowing block to be signed at a later point. This is mostly useful for tests. */ - inline abstract_builder & sign_zero () - { - block->signature.clear (); - build_state |= build_flags::signature_present; - return *this; - } + abstract_builder & sign_zero (); protected: - abstract_builder () - { - } + abstract_builder () = default; /** Create a new block and resets the internal builder state */ - inline void construct_block () - { - block = std::make_unique (); - ec.clear (); - build_state = 0; - } + void construct_block (); /** The block we're building. Clients can convert this to shared_ptr as needed. */ std::unique_ptr block; @@ -290,35 +247,35 @@ class block_builder { public: /** Prepares a new state block and returns a block builder */ - inline nano::state_block_builder & state () + nano::state_block_builder & state () { state_builder.make_block (); return state_builder; } /** Prepares a new open block and returns a block builder */ - inline nano::open_block_builder & open () + nano::open_block_builder & open () { open_builder.make_block (); return open_builder; } /** Prepares a new change block and returns a block builder */ - inline nano::change_block_builder & change () + nano::change_block_builder & change () { change_builder.make_block (); return change_builder; } /** Prepares a new send block and returns a block builder */ - inline nano::send_block_builder & send () + nano::send_block_builder & send () { send_builder.make_block (); return send_builder; } /** Prepares a new receive block and returns a block builder */ - inline nano::receive_block_builder & receive () + nano::receive_block_builder & receive () { receive_builder.make_block (); return receive_builder; diff --git a/nano/lib/blocks.cpp b/nano/lib/blocks.cpp index d8c1f2ea..06095590 100644 --- a/nano/lib/blocks.cpp +++ b/nano/lib/blocks.cpp @@ -2,10 +2,12 @@ #include #include #include -#include +#include + +#include #include -#include +#include /** Compare blocks, first by type, then content. This is an optimization over dynamic_cast, which is very slow on some platforms. */ namespace diff --git a/nano/lib/blocks.hpp b/nano/lib/blocks.hpp index b4af2962..19a090d4 100644 --- a/nano/lib/blocks.hpp +++ b/nano/lib/blocks.hpp @@ -5,7 +5,7 @@ #include #include -#include +#include #include #include diff --git a/nano/lib/config.cpp b/nano/lib/config.cpp index ab66295c..bd6dc1f8 100644 --- a/nano/lib/config.cpp +++ b/nano/lib/config.cpp @@ -1,9 +1,13 @@ #include +#include + #include namespace nano { +const char * network_constants::active_network_err_msg = "Invalid network. Valid values are live, beta and test."; + void force_nano_test_network () { nano::network_constants::set_active_network (nano::nano_networks::nano_test_network); @@ -13,4 +17,29 @@ bool running_within_valgrind () { return (RUNNING_ON_VALGRIND > 0); } + +std::string get_config_path (boost::filesystem::path const & data_path) +{ + return (data_path / "config.json").string (); +} + +std::string get_rpc_config_path (boost::filesystem::path const & data_path) +{ + return (data_path / "rpc_config.json").string (); +} + +std::string get_node_toml_config_path (boost::filesystem::path const & data_path) +{ + return (data_path / "config-node.toml").string (); +} + +std::string get_rpc_toml_config_path (boost::filesystem::path const & data_path) +{ + return (data_path / "config-rpc.toml").string (); +} + +std::string get_qtwallet_toml_config_path (boost::filesystem::path const & data_path) +{ + return (data_path / "config-qtwallet.toml").string (); +} } diff --git a/nano/lib/config.hpp b/nano/lib/config.hpp index 4c29c3a1..a65c7108 100644 --- a/nano/lib/config.hpp +++ b/nano/lib/config.hpp @@ -1,14 +1,18 @@ #pragma once -#include -#include +#include +#include -#include - -#include -#include #include +namespace boost +{ +namespace filesystem +{ + class path; +} +} + #define xstr(a) ver_str (a) #define ver_str(a) #a @@ -77,8 +81,11 @@ public: static uint64_t const publish_beta_threshold{ 0xfffffc0000000000 }; // 16x lower than full static uint64_t const publish_test_threshold{ 0xff00000000000000 }; // very low for tests + /** Error message when an invalid network is specified */ + static const char * active_network_err_msg; + /** The network this param object represents. This may differ from the global active network; this is needed for certain --debug... commands */ - nano_networks current_network; + nano_networks current_network{ nano::network_constants::active_network }; uint64_t publish_threshold; unsigned principal_weight_factor; uint16_t default_node_port; @@ -108,9 +115,9 @@ public: * If not called, the compile-time option will be used. * @param network_a The new active network. Valid values are "live", "beta" and "test" */ - static nano::error set_active_network (std::string network_a) + static bool set_active_network (std::string network_a) { - nano::error err; + auto error{ false }; if (network_a == "live") { active_network = nano::nano_networks::nano_live_network; @@ -125,9 +132,9 @@ public: } else { - err = "Invalid network. Valid values are live, beta and test."; + error = true; } - return err; + return error; } const char * get_current_network_as_string () const @@ -152,30 +159,11 @@ public: static nano::nano_networks active_network; }; -inline boost::filesystem::path get_config_path (boost::filesystem::path const & data_path) -{ - return data_path / "config.json"; -} - -inline boost::filesystem::path get_rpc_config_path (boost::filesystem::path const & data_path) -{ - return data_path / "rpc_config.json"; -} - -inline boost::filesystem::path get_node_toml_config_path (boost::filesystem::path const & data_path) -{ - return data_path / "config-node.toml"; -} - -inline boost::filesystem::path get_rpc_toml_config_path (boost::filesystem::path const & data_path) -{ - return data_path / "config-rpc.toml"; -} - -inline boost::filesystem::path get_qtwallet_toml_config_path (boost::filesystem::path const & data_path) -{ - return data_path / "config-qtwallet.toml"; -} +std::string get_config_path (boost::filesystem::path const & data_path); +std::string get_rpc_config_path (boost::filesystem::path const & data_path); +std::string get_node_toml_config_path (boost::filesystem::path const & data_path); +std::string get_rpc_toml_config_path (boost::filesystem::path const & data_path); +std::string get_qtwallet_toml_config_path (boost::filesystem::path const & data_path); /** Called by gtest_main to enforce test network */ void force_nano_test_network (); diff --git a/nano/lib/configbase.hpp b/nano/lib/configbase.hpp index 78bcc76b..f1eb1079 100644 --- a/nano/lib/configbase.hpp +++ b/nano/lib/configbase.hpp @@ -3,7 +3,6 @@ #include #include -#include #include #include @@ -35,7 +34,6 @@ template <> inline std::string type_desc (void) { return "a double preci template <> inline std::string type_desc (void) { return "a character"; } template <> inline std::string type_desc (void) { return "a string"; } template <> inline std::string type_desc (void) { return "a boolean"; } -template <> inline std::string type_desc (void) { return "an IP address"; } // clang-format on /** Base type for configuration wrappers */ diff --git a/nano/lib/errors.cpp b/nano/lib/errors.cpp index 85185529..6f0296bb 100644 --- a/nano/lib/errors.cpp +++ b/nano/lib/errors.cpp @@ -1,5 +1,9 @@ #include "nano/lib/errors.hpp" +#include + +#include + std::string nano::error_common_messages::message (int ev) const { switch (static_cast (ev)) @@ -256,3 +260,211 @@ std::string nano::error_config_messages::message (int ev) const return "Invalid error code"; } + +const char * nano::error_conversion::detail::generic_category::name () const noexcept +{ + return boost::system::generic_category ().name (); +} +std::string nano::error_conversion::detail::generic_category::message (int value) const +{ + return boost::system::generic_category ().message (value); +} + +const std::error_category & nano::error_conversion::generic_category () +{ + static detail::generic_category instance; + return instance; +} + +std::error_code nano::error_conversion::convert (const boost::system::error_code & error) +{ + if (error.category () == boost::system::generic_category ()) + { + return std::error_code (error.value (), + nano::error_conversion::generic_category ()); + } + assert (false); + + return nano::error_common::invalid_type_conversion; +} + +nano::error::error (std::error_code code_a) +{ + code = code_a; +} + +nano::error::error (boost::system::error_code const & code_a) +{ + code = std::make_error_code (static_cast (code_a.value ())); +} + +nano::error::error (std::string message_a) +{ + code = nano::error_common::generic; + message = std::move (message_a); +} + +nano::error::error (std::exception const & exception_a) +{ + code = nano::error_common::exception; + message = exception_a.what (); +} + +nano::error & nano::error::operator= (nano::error const & err_a) +{ + code = err_a.code; + message = err_a.message; + return *this; +} + +nano::error & nano::error::operator= (nano::error && err_a) +{ + code = err_a.code; + message = std::move (err_a.message); + return *this; +} + +/** Assign error code */ +nano::error & nano::error::operator= (const std::error_code code_a) +{ + code = code_a; + message.clear (); + return *this; +} + +/** Assign boost error code (as converted to std::error_code) */ +nano::error & nano::error::operator= (const boost::system::error_code & code_a) +{ + code = nano::error_conversion::convert (code_a); + message.clear (); + return *this; +} + +/** Assign boost error code (as converted to std::error_code) */ +nano::error & nano::error::operator= (const boost::system::errc::errc_t & code_a) +{ + code = nano::error_conversion::convert (boost::system::errc::make_error_code (code_a)); + message.clear (); + return *this; +} + +/** Set the error to nano::error_common::generic and the error message to \p message_a */ +nano::error & nano::error::operator= (const std::string message_a) +{ + code = nano::error_common::generic; + message = std::move (message_a); + return *this; +} + +/** Sets the error to nano::error_common::exception and adopts the exception error message. */ +nano::error & nano::error::operator= (std::exception const & exception_a) +{ + code = nano::error_common::exception; + message = exception_a.what (); + return *this; +} + +/** Return true if this#error_code equals the parameter */ +bool nano::error::operator== (const std::error_code code_a) const +{ + return code == code_a; +} + +/** Return true if this#error_code equals the parameter */ +bool nano::error::operator== (const boost::system::error_code code_a) const +{ + return code.value () == code_a.value (); +} + +/** Call the function iff the current error is zero */ +nano::error & nano::error::then (std::function next) +{ + return code ? *this : next (); +} + +/** Implicit error_code conversion */ +nano::error::operator std::error_code () const +{ + return code; +} + +/** Implicit bool conversion; true if there's an error */ +nano::error::operator bool () const +{ + return code.value () != 0; +} + +/** Implicit string conversion; returns the error message or an empty string. */ +nano::error::operator std::string () const +{ + return get_message (); +} + +/** + * Get error message, or an empty string if there's no error. If a custom error message is set, + * that will be returned, otherwise the error_code#message() is returned. + */ +std::string nano::error::get_message () const +{ + std::string res = message; + if (code && res.empty ()) + { + res = code.message (); + } + return res; +} + +/** Set an error message, but only if the error code is already set */ +nano::error & nano::error::on_error (std::string message_a) +{ + if (code) + { + message = std::move (message_a); + } + return *this; +} + +/** Set an error message if the current error code matches \p code_a */ +nano::error & nano::error::on_error (std::error_code code_a, std::string message_a) +{ + if (code == code_a) + { + message = std::move (message_a); + } + return *this; +} + +/** Set an error message and an error code */ +nano::error & nano::error::set (std::string message_a, std::error_code code_a) +{ + message = message_a; + code = code_a; + return *this; +} + +/** Set a custom error message. If the error code is not set, it will be set to nano::error_common::generic. */ +nano::error & nano::error::set_message (std::string message_a) +{ + if (!code) + { + code = nano::error_common::generic; + } + message = std::move (message_a); + return *this; +} + +/** Clear an errors */ +nano::error & nano::error::clear () +{ + code.clear (); + message.clear (); + return *this; +} + +namespace std +{ +std::error_code make_error_code (boost::system::errc::errc_t const & e) +{ + return std::error_code (static_cast (e), ::nano::error_conversion::generic_category ()); +} +} diff --git a/nano/lib/errors.hpp b/nano/lib/errors.hpp index 5be9663d..be710b2e 100644 --- a/nano/lib/errors.hpp +++ b/nano/lib/errors.hpp @@ -1,9 +1,10 @@ #pragma once +#include #include #include -#include +#include #include #include #include @@ -202,11 +203,7 @@ struct is_error_code_enum { }; -inline std::error_code make_error_code (boost::system::errc::errc_t e) -{ - return std::error_code (static_cast (e), - ::nano::error_conversion::generic_category ()); -} +std::error_code make_error_code (boost::system::errc::errc_t const & e); } namespace nano { @@ -217,33 +214,12 @@ namespace error_conversion class generic_category : public std::error_category { public: - virtual const char * name () const noexcept override - { - return boost::system::generic_category ().name (); - } - virtual std::string message (int value) const override - { - return boost::system::generic_category ().message (value); - } + const char * name () const noexcept override; + std::string message (int value) const override; }; } - inline const std::error_category & generic_category () - { - static detail::generic_category instance; - return instance; - } - - inline std::error_code convert (const boost::system::error_code & error) - { - if (error.category () == boost::system::generic_category ()) - { - return std::error_code (error.value (), - nano::error_conversion::generic_category ()); - } - assert (false); - - return nano::error_common::invalid_type_conversion; - } + const std::error_category & generic_category (); + std::error_code convert (const boost::system::error_code & error); } } @@ -257,101 +233,20 @@ public: error (nano::error const & error_a) = default; error (nano::error && error_a) = default; - error (std::error_code code_a) - { - code = code_a; - } - - error (boost::system::error_code code_a) - { - code = std::make_error_code (static_cast (code_a.value ())); - } - - error (std::string message_a) - { - code = nano::error_common::generic; - message = std::move (message_a); - } - - error (std::exception const & exception_a) - { - code = nano::error_common::exception; - message = exception_a.what (); - } - - error & operator= (nano::error const & err_a) - { - code = err_a.code; - message = err_a.message; - return *this; - } - - error & operator= (nano::error && err_a) - { - code = err_a.code; - message = std::move (err_a.message); - return *this; - } - - /** Assign error code */ - error & operator= (const std::error_code code_a) - { - code = code_a; - message.clear (); - return *this; - } - - /** Assign boost error code (as converted to std::error_code) */ - error & operator= (const boost::system::error_code & code_a) - { - code = nano::error_conversion::convert (code_a); - message.clear (); - return *this; - } - - /** Assign boost error code (as converted to std::error_code) */ - error & operator= (const boost::system::errc::errc_t & code_a) - { - code = nano::error_conversion::convert (boost::system::errc::make_error_code (code_a)); - message.clear (); - return *this; - } - - /** Set the error to nano::error_common::generic and the error message to \p message_a */ - error & operator= (const std::string message_a) - { - code = nano::error_common::generic; - message = std::move (message_a); - return *this; - } - - /** Sets the error to nano::error_common::exception and adopts the exception error message. */ - error & operator= (std::exception const & exception_a) - { - code = nano::error_common::exception; - message = exception_a.what (); - return *this; - } - - /** Return true if this#error_code equals the parameter */ - bool operator== (const std::error_code code_a) - { - return code == code_a; - } - - /** Return true if this#error_code equals the parameter */ - bool operator== (const boost::system::error_code code_a) - { - return code.value () == code_a.value (); - } - - /** Call the function iff the current error is zero */ - error & then (std::function next) - { - return code ? *this : next (); - } - - /** If the current error is one of the listed codes, reset the error code */ + error (std::error_code code_a); + error (boost::system::error_code const & code_a); + error (std::string message_a); + error (std::exception const & exception_a); + error & operator= (nano::error const & err_a); + error & operator= (nano::error && err_a); + error & operator= (const std::error_code code_a); + error & operator= (const boost::system::error_code & code_a); + error & operator= (const boost::system::errc::errc_t & code_a); + error & operator= (const std::string message_a); + error & operator= (std::exception const & exception_a); + bool operator== (const std::error_code code_a) const; + bool operator== (const boost::system::error_code code_a) const; + error & then (std::function next); template error & accept (ErrorCode... err) { @@ -365,84 +260,15 @@ public: return *this; } - /** Implicit error_code conversion */ - explicit operator std::error_code () const - { - return code; - } - - /** Implicit bool conversion; true if there's an error */ - explicit operator bool () const - { - return code.value () != 0; - } - - /** Implicit string conversion; returns the error message or an empty string. */ - explicit operator std::string () const - { - return get_message (); - } - - /** - * Get error message, or an empty string if there's no error. If a custom error message is set, - * that will be returned, otherwise the error_code#message() is returned. - */ - std::string get_message () const - { - std::string res = message; - if (code && res.empty ()) - { - res = code.message (); - } - return res; - } - - /** Set an error message, but only if the error code is already set */ - error & on_error (std::string message_a) - { - if (code) - { - message = std::move (message_a); - } - return *this; - } - - /** Set an error message if the current error code matches \p code_a */ - error & on_error (std::error_code code_a, std::string message_a) - { - if (code == code_a) - { - message = std::move (message_a); - } - return *this; - } - - /** Set an error message and an error code */ - error & set (std::string message_a, std::error_code code_a = nano::error_common::generic) - { - message = message_a; - code = code_a; - return *this; - } - - /** Set a custom error message. If the error code is not set, it will be set to nano::error_common::generic. */ - error & set_message (std::string message_a) - { - if (!code) - { - code = nano::error_common::generic; - } - message = std::move (message_a); - return *this; - } - - /** Clear an errors */ - error & clear () - { - code.clear (); - message.clear (); - return *this; - } + explicit operator std::error_code () const; + explicit operator bool () const; + explicit operator std::string () const; + std::string get_message () const; + error & on_error (std::string message_a); + error & on_error (std::error_code code_a, std::string message_a); + error & set (std::string message_a, std::error_code code_a = nano::error_common::generic); + error & set_message (std::string message_a); + error & clear (); private: std::error_code code; diff --git a/nano/lib/ipc.hpp b/nano/lib/ipc.hpp index c89cde78..60eace70 100644 --- a/nano/lib/ipc.hpp +++ b/nano/lib/ipc.hpp @@ -1,10 +1,7 @@ #pragma once -#include +#include -#include - -#include #include namespace nano diff --git a/nano/lib/ipc_client.cpp b/nano/lib/ipc_client.cpp index df07d33f..ee08f87b 100644 --- a/nano/lib/ipc_client.cpp +++ b/nano/lib/ipc_client.cpp @@ -1,3 +1,8 @@ +#include +#include +#include +#include +#include #include #include #include @@ -5,6 +10,8 @@ #include #include +#include + namespace { /** Socket agnostic IO interface */ diff --git a/nano/lib/ipc_client.hpp b/nano/lib/ipc_client.hpp index af406c4c..c2669078 100644 --- a/nano/lib/ipc_client.hpp +++ b/nano/lib/ipc_client.hpp @@ -1,13 +1,9 @@ #pragma once -#include #include #include #include -#include - -#include #include #include diff --git a/nano/lib/jsonconfig.cpp b/nano/lib/jsonconfig.cpp new file mode 100644 index 00000000..95ca65f2 --- /dev/null +++ b/nano/lib/jsonconfig.cpp @@ -0,0 +1,261 @@ +#include +#include + +#include +#include + +#include + +nano::jsonconfig::jsonconfig () : +tree (tree_default) +{ + error = std::make_shared (); +} + +nano::jsonconfig::jsonconfig (boost::property_tree::ptree & tree_a, std::shared_ptr error_a) : +nano::configbase (error_a), tree (tree_a) +{ + if (!error) + { + error = std::make_shared (); + } +} + +/** + * Reads a json object from the stream + * @return nano::error&, including a descriptive error message if the config file is malformed. + */ +nano::error & nano::jsonconfig::read (boost::filesystem::path const & path_a) +{ + std::fstream stream; + open_or_create (stream, path_a.string ()); + if (!stream.fail ()) + { + try + { + boost::property_tree::read_json (stream, tree); + } + catch (std::runtime_error const & ex) + { + auto pos (stream.tellg ()); + if (pos != std::streampos (0)) + { + *error = ex; + } + } + stream.close (); + } + return *error; +} + +void nano::jsonconfig::write (boost::filesystem::path const & path_a) +{ + std::fstream stream; + open_or_create (stream, path_a.string ()); + write (stream); +} + +void nano::jsonconfig::write (std::ostream & stream_a) const +{ + boost::property_tree::write_json (stream_a, tree); +} + +void nano::jsonconfig::read (std::istream & stream_a) +{ + boost::property_tree::read_json (stream_a, tree); +} + +/** Open configuration file, create if necessary */ +void nano::jsonconfig::open_or_create (std::fstream & stream_a, std::string const & path_a) +{ + if (!boost::filesystem::exists (path_a)) + { + // Create temp stream to first create the file + std::ofstream stream (path_a); + + // Set permissions before opening otherwise Windows only has read permissions + nano::set_secure_perm_file (path_a); + } + + stream_a.open (path_a); +} + +/** Takes a filepath, appends '_backup_' to the end (but before any extension) and saves that file in the same directory */ +void nano::jsonconfig::create_backup_file (boost::filesystem::path const & filepath_a) +{ + auto extension = filepath_a.extension (); + auto filename_without_extension = filepath_a.filename ().replace_extension (""); + auto orig_filepath = filepath_a; + auto & backup_path = orig_filepath.remove_filename (); + auto backup_filename = filename_without_extension; + backup_filename += "_backup_"; + backup_filename += std::to_string (std::chrono::system_clock::now ().time_since_epoch ().count ()); + backup_filename += extension; + auto backup_filepath = backup_path / backup_filename; + + boost::filesystem::copy_file (filepath_a, backup_filepath); +} + +/** Returns the boost property node managed by this instance */ +boost::property_tree::ptree const & nano::jsonconfig::get_tree () +{ + return tree; +} + +/** Returns true if the property tree node is empty */ +bool nano::jsonconfig::empty () const +{ + return tree.empty (); +} + +boost::optional nano::jsonconfig::get_optional_child (std::string const & key_a) +{ + boost::optional child_config; + auto child = tree.get_child_optional (key_a); + if (child) + { + return jsonconfig (child.get (), error); + } + return child_config; +} + +nano::jsonconfig nano::jsonconfig::get_required_child (std::string const & key_a) +{ + auto child = tree.get_child_optional (key_a); + if (!child) + { + *error = nano::error_config::missing_value; + error->set_message ("Missing configuration node: " + key_a); + } + return child ? jsonconfig (child.get (), error) : *this; +} + +nano::jsonconfig & nano::jsonconfig::put_child (std::string const & key_a, nano::jsonconfig & conf_a) +{ + tree.add_child (key_a, conf_a.get_tree ()); + return *this; +} + +nano::jsonconfig & nano::jsonconfig::replace_child (std::string const & key_a, nano::jsonconfig & conf_a) +{ + tree.erase (key_a); + put_child (key_a, conf_a); + return *this; +} + +/** Returns true if \p key_a is present */ +bool nano::jsonconfig::has_key (std::string const & key_a) +{ + return tree.find (key_a) != tree.not_found (); +} + +/** Erase the property of given key */ +nano::jsonconfig & nano::jsonconfig::erase (std::string const & key_a) +{ + tree.erase (key_a); + return *this; +} + +// boost's lexical cast doesn't handle (u)int8_t +nano::jsonconfig & nano::jsonconfig::get_config (bool optional, std::string key, uint8_t & target, uint8_t default_value) +{ + int64_t tmp; + try + { + auto val (tree.get (key)); + if (!boost::conversion::try_lexical_convert (val, tmp) || tmp < 0 || tmp > 255) + { + conditionally_set_error (nano::error_config::invalid_value, optional, key); + } + else + { + target = static_cast (tmp); + } + } + catch (boost::property_tree::ptree_bad_path const &) + { + if (!optional) + { + conditionally_set_error (nano::error_config::missing_value, optional, key); + } + else + { + target = default_value; + } + } + catch (std::runtime_error & ex) + { + conditionally_set_error (ex, optional, key); + } + return *this; +} + +nano::jsonconfig & nano::jsonconfig::get_config (bool optional, std::string key, bool & target, bool default_value) +{ + auto bool_conv = [this, &target, &key, optional](std::string val) { + if (val == "true") + { + target = true; + } + else if (val == "false") + { + target = false; + } + else if (!*error) + { + conditionally_set_error (nano::error_config::invalid_value, optional, key); + } + }; + try + { + auto val (tree.get (key)); + bool_conv (val); + } + catch (boost::property_tree::ptree_bad_path const &) + { + if (!optional) + { + conditionally_set_error (nano::error_config::missing_value, optional, key); + } + else + { + target = default_value; + } + } + catch (std::runtime_error & ex) + { + conditionally_set_error (ex, optional, key); + } + return *this; +} + +nano::jsonconfig & nano::jsonconfig::get_config (bool optional, std::string key, boost::asio::ip::address_v6 & target, boost::asio::ip::address_v6 const & default_value) +{ + try + { + auto address_l (tree.get (key)); + boost::system::error_code bec; + target = boost::asio::ip::make_address_v6 (address_l, bec); + if (bec) + { + conditionally_set_error (nano::error_config::invalid_value, optional, key); + } + } + catch (boost::property_tree::ptree_bad_path const &) + { + if (!optional) + { + conditionally_set_error (nano::error_config::missing_value, optional, key); + } + else + { + target = default_value; + } + } + return *this; +} + +void nano::jsonconfig::write_json (std::fstream & stream) +{ + boost::property_tree::write_json (stream, tree); +} diff --git a/nano/lib/jsonconfig.hpp b/nano/lib/jsonconfig.hpp index ce9d47ab..2c8fab68 100644 --- a/nano/lib/jsonconfig.hpp +++ b/nano/lib/jsonconfig.hpp @@ -1,63 +1,35 @@ #pragma once -#include #include #include #include -#include +#include #include -#include +#include #include +namespace boost +{ +namespace asio +{ + namespace ip + { + class address_v6; + } +} +} + namespace nano { /** Manages a node in a boost configuration tree. */ class jsonconfig : public nano::configbase { public: - jsonconfig () : - tree (tree_default) - { - error = std::make_shared (); - } - - jsonconfig (boost::property_tree::ptree & tree_a, std::shared_ptr error_a = nullptr) : - nano::configbase (error_a), tree (tree_a) - { - if (!error) - { - error = std::make_shared (); - } - } - - /** - * Reads a json object from the stream - * @return nano::error&, including a descriptive error message if the config file is malformed. - */ - nano::error & read (boost::filesystem::path const & path_a) - { - std::fstream stream; - open_or_create (stream, path_a.string ()); - if (!stream.fail ()) - { - try - { - boost::property_tree::read_json (stream, tree); - } - catch (std::runtime_error const & ex) - { - auto pos (stream.tellg ()); - if (pos != std::streampos (0)) - { - *error = ex; - } - } - stream.close (); - } - return *error; - } + jsonconfig (); + jsonconfig (boost::property_tree::ptree & tree_a, std::shared_ptr error_a = nullptr); + nano::error & read (boost::filesystem::path const & path_a); /** * Reads a json object from the stream and if it was changed, write the object back to the stream. @@ -83,7 +55,7 @@ public: stream.open (path_a.string (), std::ios_base::out | std::ios_base::trunc); try { - boost::property_tree::write_json (stream, tree); + write_json (stream); } catch (std::runtime_error const & ex) { @@ -95,100 +67,19 @@ public: return *error; } - void write (boost::filesystem::path const & path_a) - { - std::fstream stream; - open_or_create (stream, path_a.string ()); - write (stream); - } - - void write (std::ostream & stream_a) const - { - boost::property_tree::write_json (stream_a, tree); - } - - void read (std::istream & stream_a) - { - boost::property_tree::read_json (stream_a, tree); - } - - /** Open configuration file, create if necessary */ - void open_or_create (std::fstream & stream_a, std::string const & path_a) - { - if (!boost::filesystem::exists (path_a)) - { - // Create temp stream to first create the file - std::ofstream stream (path_a); - - // Set permissions before opening otherwise Windows only has read permissions - nano::set_secure_perm_file (path_a); - } - - stream_a.open (path_a); - } - - /** Takes a filepath, appends '_backup_' to the end (but before any extension) and saves that file in the same directory */ - void create_backup_file (boost::filesystem::path const & filepath_a) - { - auto extension = filepath_a.extension (); - auto filename_without_extension = filepath_a.filename ().replace_extension (""); - auto orig_filepath = filepath_a; - auto & backup_path = orig_filepath.remove_filename (); - auto backup_filename = filename_without_extension; - backup_filename += "_backup_"; - backup_filename += std::to_string (std::chrono::system_clock::now ().time_since_epoch ().count ()); - backup_filename += extension; - auto backup_filepath = backup_path / backup_filename; - - boost::filesystem::copy_file (filepath_a, backup_filepath); - } - - /** Returns the boost property node managed by this instance */ - boost::property_tree::ptree const & get_tree () - { - return tree; - } - - /** Returns true if the property tree node is empty */ - bool empty () const - { - return tree.empty (); - } - - boost::optional get_optional_child (std::string const & key_a) - { - boost::optional child_config; - auto child = tree.get_child_optional (key_a); - if (child) - { - return jsonconfig (child.get (), error); - } - return child_config; - } - - jsonconfig get_required_child (std::string const & key_a) - { - auto child = tree.get_child_optional (key_a); - if (!child) - { - *error = nano::error_config::missing_value; - error->set_message ("Missing configuration node: " + key_a); - } - return child ? jsonconfig (child.get (), error) : *this; - } - - jsonconfig & put_child (std::string const & key_a, nano::jsonconfig & conf_a) - { - tree.add_child (key_a, conf_a.get_tree ()); - return *this; - } - - jsonconfig & replace_child (std::string const & key_a, nano::jsonconfig & conf_a) - { - tree.erase (key_a); - put_child (key_a, conf_a); - return *this; - } + void write (boost::filesystem::path const & path_a); + void write (std::ostream & stream_a) const; + void read (std::istream & stream_a); + void open_or_create (std::fstream & stream_a, std::string const & path_a); + void create_backup_file (boost::filesystem::path const & filepath_a); + boost::property_tree::ptree const & get_tree (); + bool empty () const; + boost::optional get_optional_child (std::string const & key_a); + jsonconfig get_required_child (std::string const & key_a); + jsonconfig & put_child (std::string const & key_a, nano::jsonconfig & conf_a); + jsonconfig & replace_child (std::string const & key_a, nano::jsonconfig & conf_a); + bool has_key (std::string const & key_a); + jsonconfig & erase (std::string const & key_a); /** Set value for the given key. Any existing value will be overwritten. */ template @@ -208,19 +99,6 @@ public: return *this; } - /** Returns true if \p key_a is present */ - bool has_key (std::string const & key_a) - { - return tree.find (key_a) != tree.not_found (); - } - - /** Erase the property of given key */ - jsonconfig & erase (std::string const & key_a) - { - tree.erase (key_a); - return *this; - } - /** Iterate array entries */ template jsonconfig & array_entries (std::function callback) @@ -236,7 +114,7 @@ public: template jsonconfig & get_optional (std::string const & key, T & target, T default_value) { - get_config (true, key, target, default_value); + get_config (true, key, target, default_value); return *this; } @@ -247,7 +125,7 @@ public: template jsonconfig & get_optional (std::string const & key, T & target) { - get_config (true, key, target, target); + get_config (true, key, target, target); return *this; } @@ -259,7 +137,7 @@ public: if (has_key (key)) { T target{}; - get_config (true, key, target, target); + get_config (true, key, target, target); res = target; } return res; @@ -269,7 +147,7 @@ public: template jsonconfig & get (std::string const & key, T & target) { - get_config (true, key, target, target); + get_config (true, key, target, target); return *this; } @@ -280,7 +158,7 @@ public: T get (std::string const & key) { T target{}; - get_config (true, key, target, target); + get_config (true, key, target, target); return target; } @@ -291,7 +169,14 @@ public: template jsonconfig & get_required (std::string const & key, T & target) { - get_config (false, key, target); + get_config (false, key, target); + return *this; + } + + template + jsonconfig & get_required (std::string const & key, T & target, T const & default_value) + { + get_config (false, key, target, default_value); return *this; } @@ -326,110 +211,15 @@ protected: } // boost's lexical cast doesn't handle (u)int8_t - template ::value>> - jsonconfig & get_config (bool optional, std::string key, uint8_t & target, uint8_t default_value = T ()) - { - int64_t tmp; - try - { - auto val (tree.get (key)); - if (!boost::conversion::try_lexical_convert (val, tmp) || tmp < 0 || tmp > 255) - { - conditionally_set_error (nano::error_config::invalid_value, optional, key); - } - else - { - target = static_cast (tmp); - } - } - catch (boost::property_tree::ptree_bad_path const &) - { - if (!optional) - { - conditionally_set_error (nano::error_config::missing_value, optional, key); - } - else - { - target = default_value; - } - } - catch (std::runtime_error & ex) - { - conditionally_set_error (ex, optional, key); - } - return *this; - } - - template ::value>> - jsonconfig & get_config (bool optional, std::string key, bool & target, bool default_value = false) - { - auto bool_conv = [this, &target, &key, optional](std::string val) { - if (val == "true") - { - target = true; - } - else if (val == "false") - { - target = false; - } - else if (!*error) - { - conditionally_set_error (nano::error_config::invalid_value, optional, key); - } - }; - try - { - auto val (tree.get (key)); - bool_conv (val); - } - catch (boost::property_tree::ptree_bad_path const &) - { - if (!optional) - { - conditionally_set_error (nano::error_config::missing_value, optional, key); - } - else - { - target = default_value; - } - } - catch (std::runtime_error & ex) - { - conditionally_set_error (ex, optional, key); - } - return *this; - } - - template ::value>> - jsonconfig & get_config (bool optional, std::string key, boost::asio::ip::address_v6 & target, boost::asio::ip::address_v6 default_value = T ()) - { - try - { - auto address_l (tree.get (key)); - boost::system::error_code bec; - target = boost::asio::ip::address_v6::from_string (address_l, bec); - if (bec) - { - conditionally_set_error (nano::error_config::invalid_value, optional, key); - } - } - catch (boost::property_tree::ptree_bad_path const &) - { - if (!optional) - { - conditionally_set_error (nano::error_config::missing_value, optional, key); - } - else - { - target = default_value; - } - } - return *this; - } + jsonconfig & get_config (bool optional, std::string key, uint8_t & target, uint8_t default_value = uint8_t ()); + jsonconfig & get_config (bool optional, std::string key, bool & target, bool default_value = false); + jsonconfig & get_config (bool optional, std::string key, boost::asio::ip::address_v6 & target, boost::asio::ip::address_v6 const & default_value); private: /** The property node being managed */ boost::property_tree::ptree & tree; boost::property_tree::ptree tree_default; + + void write_json (std::fstream & stream); }; } diff --git a/nano/lib/locks.cpp b/nano/lib/locks.cpp index 07589727..e38a4e17 100644 --- a/nano/lib/locks.cpp +++ b/nano/lib/locks.cpp @@ -1,6 +1,8 @@ #include #include +#include + #if NANO_TIMED_LOCKS > 0 namespace { diff --git a/nano/lib/numbers.hpp b/nano/lib/numbers.hpp index 4735af1b..ee45ba76 100644 --- a/nano/lib/numbers.hpp +++ b/nano/lib/numbers.hpp @@ -1,7 +1,5 @@ #pragma once -#include - #include namespace nano diff --git a/nano/lib/plat/darwin/thread_role.cpp b/nano/lib/plat/darwin/thread_role.cpp index fb0f3f02..dd9bdc61 100644 --- a/nano/lib/plat/darwin/thread_role.cpp +++ b/nano/lib/plat/darwin/thread_role.cpp @@ -1,4 +1,4 @@ -#include +#include #include diff --git a/nano/lib/plat/freebsd/thread_role.cpp b/nano/lib/plat/freebsd/thread_role.cpp index 7be32ab2..44699ae8 100644 --- a/nano/lib/plat/freebsd/thread_role.cpp +++ b/nano/lib/plat/freebsd/thread_role.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include diff --git a/nano/lib/plat/linux/debugging.cpp b/nano/lib/plat/linux/debugging.cpp index 41b06863..cbfb5e27 100644 --- a/nano/lib/plat/linux/debugging.cpp +++ b/nano/lib/plat/linux/debugging.cpp @@ -5,6 +5,9 @@ #include #include +#include +#include + namespace { // This creates a file for the load address of an executable or shared library. diff --git a/nano/lib/plat/linux/thread_role.cpp b/nano/lib/plat/linux/thread_role.cpp index af0a492a..46d29522 100644 --- a/nano/lib/plat/linux/thread_role.cpp +++ b/nano/lib/plat/linux/thread_role.cpp @@ -1,4 +1,4 @@ -#include +#include #include diff --git a/nano/lib/plat/windows/perms.cpp b/nano/lib/plat/windows/perms.cpp index 7bb9b188..e2b188a9 100644 --- a/nano/lib/plat/windows/perms.cpp +++ b/nano/lib/plat/windows/perms.cpp @@ -4,10 +4,13 @@ #include +// clang-format off +// Keep windows.h header at the top +#include #include #include #include -#include +// clang-format on void nano::set_umask () { diff --git a/nano/lib/plat/windows/thread_role.cpp b/nano/lib/plat/windows/thread_role.cpp index ad1913a1..a604e67b 100644 --- a/nano/lib/plat/windows/thread_role.cpp +++ b/nano/lib/plat/windows/thread_role.cpp @@ -1,7 +1,6 @@ -#include +#include #include -#include void nano::thread_role::set_os_name (std::string const & thread_name) { diff --git a/nano/lib/rpcconfig.cpp b/nano/lib/rpcconfig.cpp index 5b57da0e..f34f2bd5 100644 --- a/nano/lib/rpcconfig.cpp +++ b/nano/lib/rpcconfig.cpp @@ -1,3 +1,4 @@ +#include #include #include #include @@ -53,7 +54,13 @@ nano::error nano::rpc_secure_config::deserialize_toml (nano::tomlconfig & toml) return toml.get_error (); } +nano::rpc_config::rpc_config () : +address (boost::asio::ip::address_v6::loopback ().to_string ()) +{ +} + nano::rpc_config::rpc_config (uint16_t port_a, bool enable_control_a) : +address (boost::asio::ip::address_v6::loopback ().to_string ()), port (port_a), enable_control (enable_control_a) { @@ -62,7 +69,7 @@ enable_control (enable_control_a) nano::error nano::rpc_config::serialize_json (nano::jsonconfig & json) const { json.put ("version", json_version ()); - json.put ("address", address.to_string ()); + json.put ("address", address); json.put ("port", port); json.put ("enable_control", enable_control); json.put ("max_json_depth", max_json_depth); @@ -107,7 +114,9 @@ nano::error nano::rpc_config::deserialize_json (bool & upgraded_a, nano::jsoncon secure.deserialize_json (*rpc_secure_l); } - json.get_required ("address", address); + boost::asio::ip::address_v6 address_l; + json.get_required ("address", address_l, boost::asio::ip::address_v6::loopback ()); + address = address_l.to_string (); json.get_optional ("port", port); json.get_optional ("enable_control", enable_control); json.get_optional ("max_json_depth", max_json_depth); @@ -127,7 +136,9 @@ nano::error nano::rpc_config::deserialize_json (bool & upgraded_a, nano::jsoncon rpc_process_l->get_optional ("io_threads", rpc_process.io_threads); rpc_process_l->get_optional ("ipc_port", rpc_process.ipc_port); - rpc_process_l->get_optional ("ipc_address", rpc_process.ipc_address); + boost::asio::ip::address_v6 ipc_address_l; + rpc_process_l->get_optional ("ipc_address", ipc_address_l); + rpc_process.ipc_address = ipc_address_l.to_string (); rpc_process_l->get_optional ("num_ipc_connections", rpc_process.num_ipc_connections); } } @@ -142,7 +153,7 @@ nano::error nano::rpc_config::deserialize_json (bool & upgraded_a, nano::jsoncon nano::error nano::rpc_config::serialize_toml (nano::tomlconfig & toml) const { - toml.put ("address", address.to_string (), "Bind address for the RPC server.\ntype:string,ip"); + toml.put ("address", address, "Bind address for the RPC server.\ntype:string,ip"); toml.put ("port", port, "Listening port for the RPC server.\ntype:uint16"); toml.put ("enable_control", enable_control, "Enable or disable control-level requests.\nWARNING: Enabling this gives anyone with RPC access the ability to stop the node and access wallet funds.\ntype:bool"); toml.put ("max_json_depth", max_json_depth, "Maximum number of levels in JSON requests.\ntype:uint8"); @@ -150,7 +161,7 @@ nano::error nano::rpc_config::serialize_toml (nano::tomlconfig & toml) const nano::tomlconfig rpc_process_l; rpc_process_l.put ("io_threads", rpc_process.io_threads, "Number of threads used to serve IO.\ntype:uint32"); - rpc_process_l.put ("ipc_address", rpc_process.ipc_address.to_string (), "Address of IPC server.\ntype:string,ip"); + rpc_process_l.put ("ipc_address", rpc_process.ipc_address, "Address of IPC server.\ntype:string,ip"); rpc_process_l.put ("ipc_port", rpc_process.ipc_port, "Listening port of IPC server.\ntype:uint16"); rpc_process_l.put ("num_ipc_connections", rpc_process.num_ipc_connections, "Number of IPC connections to establish.\ntype:uint32"); toml.put_child ("process", rpc_process_l); @@ -167,7 +178,9 @@ nano::error nano::rpc_config::deserialize_toml (nano::tomlconfig & toml) secure.deserialize_toml (*rpc_secure_l); } - toml.get_optional ("address", address); + boost::asio::ip::address_v6 address_l; + toml.get_optional ("address", address_l, boost::asio::ip::address_v6::loopback ()); + address = address_l.to_string (); toml.get_optional ("port", port); toml.get_optional ("enable_control", enable_control); toml.get_optional ("max_json_depth", max_json_depth); @@ -178,7 +191,9 @@ nano::error nano::rpc_config::deserialize_toml (nano::tomlconfig & toml) { rpc_process_l->get_optional ("io_threads", rpc_process.io_threads); rpc_process_l->get_optional ("ipc_port", rpc_process.ipc_port); - rpc_process_l->get_optional ("ipc_address", rpc_process.ipc_address); + boost::asio::ip::address_v6 ipc_address_l; + rpc_process_l->get_optional ("ipc_address", ipc_address_l, boost::asio::ip::address_v6::loopback ()); + rpc_process.ipc_address = address_l.to_string (); rpc_process_l->get_optional ("num_ipc_connections", rpc_process.num_ipc_connections); } } @@ -186,6 +201,11 @@ nano::error nano::rpc_config::deserialize_toml (nano::tomlconfig & toml) return toml.get_error (); } +nano::rpc_process_config::rpc_process_config () : +ipc_address (boost::asio::ip::address_v6::loopback ().to_string ()) +{ +} + namespace nano { nano::error read_rpc_config_toml (boost::filesystem::path const & data_path_a, nano::rpc_config & config_a, std::vector const & config_overrides) diff --git a/nano/lib/rpcconfig.hpp b/nano/lib/rpcconfig.hpp index 88ec8180..fe704052 100644 --- a/nano/lib/rpcconfig.hpp +++ b/nano/lib/rpcconfig.hpp @@ -1,15 +1,20 @@ #pragma once -#include #include #include -#include -#include - #include +#include #include +namespace boost +{ +namespace filesystem +{ + class path; +} +} + namespace nano { class jsonconfig; @@ -43,9 +48,10 @@ public: class rpc_process_config final { public: + rpc_process_config (); nano::network_constants network_constants; - unsigned io_threads{ std::max (4, boost::thread::hardware_concurrency ()) }; - boost::asio::ip::address_v6 ipc_address{ boost::asio::ip::address_v6::loopback () }; + unsigned io_threads{ (4 < std::thread::hardware_concurrency ()) ? std::thread::hardware_concurrency () : 4 }; + std::string ipc_address; uint16_t ipc_port{ network_constants.default_ipc_port }; unsigned num_ipc_connections{ network_constants.is_live_network () ? 8u : network_constants.is_beta_network () ? 4u : 1u }; static unsigned json_version () @@ -57,7 +63,7 @@ public: class rpc_config final { public: - rpc_config () = default; + rpc_config (); explicit rpc_config (uint16_t, bool); nano::error serialize_json (nano::jsonconfig &) const; nano::error deserialize_json (bool & upgraded_a, nano::jsonconfig &); @@ -65,7 +71,7 @@ public: nano::error deserialize_toml (nano::tomlconfig &); nano::rpc_process_config rpc_process; - boost::asio::ip::address_v6 address{ boost::asio::ip::address_v6::loopback () }; + std::string address; uint16_t port{ rpc_process.network_constants.default_rpc_port }; bool enable_control{ false }; rpc_secure_config secure; diff --git a/nano/lib/stats.cpp b/nano/lib/stats.cpp index 9a6f44fe..257fa6b4 100644 --- a/nano/lib/stats.cpp +++ b/nano/lib/stats.cpp @@ -1,4 +1,5 @@ -#include +#include +#include #include #include @@ -7,9 +8,7 @@ #include #include -#include #include -#include nano::error nano::stat_config::deserialize_json (nano::jsonconfig & json) { @@ -655,3 +654,53 @@ std::string nano::stat::dir_to_string (uint32_t key) } return res; } + +nano::stat_datapoint::stat_datapoint (stat_datapoint const & other_a) +{ + nano::lock_guard lock (other_a.datapoint_mutex); + value = other_a.value; + timestamp = other_a.timestamp; +} + +nano::stat_datapoint & nano::stat_datapoint::operator= (stat_datapoint const & other_a) +{ + nano::lock_guard lock (other_a.datapoint_mutex); + value = other_a.value; + timestamp = other_a.timestamp; + return *this; +} + +uint64_t nano::stat_datapoint::get_value () const +{ + nano::lock_guard lock (datapoint_mutex); + return value; +} + +void nano::stat_datapoint::set_value (uint64_t value_a) +{ + nano::lock_guard lock (datapoint_mutex); + value = value_a; +} + +std::chrono::system_clock::time_point nano::stat_datapoint::get_timestamp () const +{ + nano::lock_guard lock (datapoint_mutex); + return timestamp; +} + +void nano::stat_datapoint::set_timestamp (std::chrono::system_clock::time_point timestamp_a) +{ + nano::lock_guard lock (datapoint_mutex); + timestamp = timestamp_a; +} + +/** Add \addend to the current value and optionally update the timestamp */ +void nano::stat_datapoint::add (uint64_t addend, bool update_timestamp) +{ + nano::lock_guard lock (datapoint_mutex); + value += addend; + if (update_timestamp) + { + timestamp = std::chrono::system_clock::now (); + } +} diff --git a/nano/lib/stats.hpp b/nano/lib/stats.hpp index 47fd49b9..92c9650b 100644 --- a/nano/lib/stats.hpp +++ b/nano/lib/stats.hpp @@ -1,24 +1,21 @@ #pragma once #include -#include #include #include -#include -#include #include #include #include #include #include -#include namespace nano { class node; class tomlconfig; +class jsonconfig; /** * Serialize and deserialize the 'statistics' node from config.json * All configuration values have defaults. In particular, file logging of statistics @@ -65,50 +62,13 @@ class stat_datapoint final { public: stat_datapoint () = default; - stat_datapoint (stat_datapoint const & other_a) - { - nano::lock_guard lock (other_a.datapoint_mutex); - value = other_a.value; - timestamp = other_a.timestamp; - } - stat_datapoint & operator= (stat_datapoint const & other_a) - { - nano::lock_guard lock (other_a.datapoint_mutex); - value = other_a.value; - timestamp = other_a.timestamp; - return *this; - } - - uint64_t get_value () - { - nano::lock_guard lock (datapoint_mutex); - return value; - } - void set_value (uint64_t value_a) - { - nano::lock_guard lock (datapoint_mutex); - value = value_a; - } - std::chrono::system_clock::time_point get_timestamp () - { - nano::lock_guard lock (datapoint_mutex); - return timestamp; - } - void set_timestamp (std::chrono::system_clock::time_point timestamp_a) - { - nano::lock_guard lock (datapoint_mutex); - timestamp = timestamp_a; - } - /** Add \addend to the current value and optionally update the timestamp */ - void add (uint64_t addend, bool update_timestamp = true) - { - nano::lock_guard lock (datapoint_mutex); - value += addend; - if (update_timestamp) - { - timestamp = std::chrono::system_clock::now (); - } - } + stat_datapoint (stat_datapoint const & other_a); + stat_datapoint & operator= (stat_datapoint const & other_a); + uint64_t get_value () const; + void set_value (uint64_t value_a); + std::chrono::system_clock::time_point get_timestamp () const; + void set_timestamp (std::chrono::system_clock::time_point timestamp_a); + void add (uint64_t addend, bool update_timestamp = true); private: mutable std::mutex datapoint_mutex; diff --git a/nano/lib/threading.cpp b/nano/lib/threading.cpp new file mode 100644 index 00000000..67daced7 --- /dev/null +++ b/nano/lib/threading.cpp @@ -0,0 +1,166 @@ +#include + +#include + +namespace nano +{ +namespace thread_role +{ + /* + * nano::thread_role namespace + * + * Manage thread role + */ + static thread_local nano::thread_role::name current_thread_role = nano::thread_role::name::unknown; + nano::thread_role::name get () + { + return current_thread_role; + } + + std::string get_string (nano::thread_role::name role) + { + std::string thread_role_name_string; + + switch (role) + { + case nano::thread_role::name::unknown: + thread_role_name_string = ""; + break; + case nano::thread_role::name::io: + thread_role_name_string = "I/O"; + break; + case nano::thread_role::name::work: + thread_role_name_string = "Work pool"; + break; + case nano::thread_role::name::packet_processing: + thread_role_name_string = "Pkt processing"; + break; + case nano::thread_role::name::alarm: + thread_role_name_string = "Alarm"; + break; + case nano::thread_role::name::vote_processing: + thread_role_name_string = "Vote processing"; + break; + case nano::thread_role::name::block_processing: + thread_role_name_string = "Blck processing"; + break; + case nano::thread_role::name::request_loop: + thread_role_name_string = "Request loop"; + break; + case nano::thread_role::name::wallet_actions: + thread_role_name_string = "Wallet actions"; + break; + case nano::thread_role::name::work_watcher: + thread_role_name_string = "Work watcher"; + break; + case nano::thread_role::name::bootstrap_initiator: + thread_role_name_string = "Bootstrap init"; + break; + case nano::thread_role::name::voting: + thread_role_name_string = "Voting"; + break; + case nano::thread_role::name::signature_checking: + thread_role_name_string = "Signature check"; + break; + case nano::thread_role::name::rpc_request_processor: + thread_role_name_string = "RPC processor"; + break; + case nano::thread_role::name::rpc_process_container: + thread_role_name_string = "RPC process"; + break; + case nano::thread_role::name::confirmation_height_processing: + thread_role_name_string = "Conf height"; + break; + case nano::thread_role::name::worker: + thread_role_name_string = "Worker"; + break; + } + + /* + * We want to constrain the thread names to 15 + * characters, since this is the smallest maximum + * length supported by the platforms we support + * (specifically, Linux) + */ + assert (thread_role_name_string.size () < 16); + return (thread_role_name_string); + } + + std::string get_string () + { + return get_string (current_thread_role); + } + + void set (nano::thread_role::name role) + { + auto thread_role_name_string (get_string (role)); + + nano::thread_role::set_os_name (thread_role_name_string); + + nano::thread_role::current_thread_role = role; + } +} +} + +void nano::thread_attributes::set (boost::thread::attributes & attrs) +{ + auto attrs_l (&attrs); + attrs_l->set_stack_size (8000000); //8MB +} + +nano::thread_runner::thread_runner (boost::asio::io_context & io_ctx_a, unsigned service_threads_a) : +io_guard (boost::asio::make_work_guard (io_ctx_a)) +{ + boost::thread::attributes attrs; + nano::thread_attributes::set (attrs); + for (auto i (0u); i < service_threads_a; ++i) + { + threads.push_back (boost::thread (attrs, [&io_ctx_a]() { + nano::thread_role::set (nano::thread_role::name::io); + try + { + io_ctx_a.run (); + } + catch (std::exception const & ex) + { + std::cerr << ex.what () << std::endl; +#ifndef NDEBUG + throw; +#endif + } + catch (...) + { +#ifndef NDEBUG + /* + * In a release build, catch and swallow the + * io_context exception, in debug mode pass it + * on + */ + throw; +#endif + } + })); + } +} + +nano::thread_runner::~thread_runner () +{ + join (); +} + +void nano::thread_runner::join () +{ + io_guard.reset (); + for (auto & i : threads) + { + if (i.joinable ()) + { + i.join (); + } + } +} + +void nano::thread_runner::stop_event_processing () +{ + io_guard.get_executor ().context ().stop (); +} diff --git a/nano/lib/threading.hpp b/nano/lib/threading.hpp new file mode 100644 index 00000000..9f56c6d5 --- /dev/null +++ b/nano/lib/threading.hpp @@ -0,0 +1,75 @@ +#pragma once + +#include +#include +#include + +#include + +namespace nano +{ +/* + * Functions for understanding the role of the current thread + */ +namespace thread_role +{ + enum class name + { + unknown, + io, + work, + packet_processing, + alarm, + vote_processing, + block_processing, + request_loop, + wallet_actions, + bootstrap_initiator, + voting, + signature_checking, + rpc_request_processor, + rpc_process_container, + work_watcher, + confirmation_height_processing, + worker + }; + /* + * Get/Set the identifier for the current thread + */ + nano::thread_role::name get (); + void set (nano::thread_role::name); + + /* + * Get the thread name as a string from enum + */ + std::string get_string (nano::thread_role::name); + + /* + * Get the current thread's role as a string + */ + std::string get_string (); + + /* + * Internal only, should not be called directly + */ + void set_os_name (std::string const &); +} + +namespace thread_attributes +{ + void set (boost::thread::attributes &); +} + +class thread_runner final +{ +public: + thread_runner (boost::asio::io_context &, unsigned); + ~thread_runner (); + /** Tells the IO context to stop processing events.*/ + void stop_event_processing (); + /** Wait for IO threads to complete */ + void join (); + std::vector threads; + boost::asio::executor_work_guard io_guard; +}; +} \ No newline at end of file diff --git a/nano/lib/timer.cpp b/nano/lib/timer.cpp new file mode 100644 index 00000000..1ff7b630 --- /dev/null +++ b/nano/lib/timer.cpp @@ -0,0 +1,246 @@ +#include + +#include +#include +#include + +namespace +{ +template ::value> * = nullptr> +std::string typed_unit () +{ + return "nanoseconds"; +} + +template ::value> * = nullptr> +std::string typed_unit () +{ + return "microseconds"; +} + +template ::value> * = nullptr> +std::string typed_unit () +{ + return "milliseconds"; +} + +template ::value> * = nullptr> +std::string typed_unit () +{ + return "seconds"; +} + +template ::value> * = nullptr> +std::string typed_unit () +{ + return "minutes"; +} + +template ::value> * = nullptr> +std::string typed_unit () +{ + return "hours"; +} +} + +template +nano::timer::timer (nano::timer_state state_a, std::string const & description_a) : +desc (description_a) +{ + if (state_a == nano::timer_state::started) + { + start (); + } +} + +template +nano::timer::timer (std::string const & description_a) : +desc (description_a) +{ +} + +template +nano::timer::timer (std::string const & description_a, nano::timer * parent_a) : +parent (parent_a), +desc (description_a) +{ +} + +/** Do not output if measured time is below the time units threshold in \p minimum_a */ +template +nano::timer & nano::timer::set_minimum (UNIT minimum_a) +{ + minimum = minimum_a; + return *this; +} + +/** + * Create a child timer without starting it. + * Since the timing API needs to have low overhead, this function + * does not check if a timer with the same name already exists. + */ +template +nano::timer & nano::timer::child (std::string const & description_a) +{ + children.emplace_back (description_a, this); + return children.back (); +} + +/** Create and start a child timer */ +template +nano::timer & nano::timer::start_child (std::string const & description_a) +{ + auto & child_timer = child (description_a); + child_timer.start (); + return child_timer; +} + +/** Start the timer. This will assert if the timer is already started. */ +template +void nano::timer::start () +{ + assert (state == nano::timer_state::stopped); + state = nano::timer_state::started; + begin = CLOCK::now (); +} + +/** Restarts the timer */ +template +void nano::timer::restart () +{ + state = nano::timer_state::started; + begin = CLOCK::now (); + ticks = UNIT::zero (); + measurements = 0; +} + +/** + * Stops the timer and increases the measurement count. A timer can be started and paused + * multiple times (e.g. in a loop). + * @return duration + */ +template +UNIT nano::timer::pause () +{ + ++measurements; + return stop (); +} + +/** + * Stop timer + * @return duration + */ +template +UNIT nano::timer::stop () +{ + assert (state == nano::timer_state::started); + state = nano::timer_state::stopped; + + auto end = CLOCK::now (); + ticks += std::chrono::duration_cast (end - begin); + return ticks; +} + +/** + * Return current units. + */ +template +UNIT nano::timer::value () const +{ + return ticks; +} + +/** Returns the duration in UNIT since the timer was last started. */ +template +UNIT nano::timer::since_start () const +{ + auto end = CLOCK::now (); + return std::chrono::duration_cast (end - begin); +} + +/** Returns true if the timer was last started longer than \p duration_a units ago*/ +template +bool nano::timer::after_deadline (UNIT duration_a) +{ + auto end = CLOCK::now (); + return std::chrono::duration_cast (end - begin) > duration_a; +} + +/** Returns true if the timer was last started shorter than \p duration_a units ago*/ +template +bool nano::timer::before_deadline (UNIT duration_a) +{ + auto end = CLOCK::now (); + return std::chrono::duration_cast (end - begin) < duration_a; +} + +/** Stop timer and write measurements to \p stream_a */ +template +void nano::timer::stop (std::ostream & stream_a) +{ + stop (); + print (stream_a); +} + +/** Stop timer and write measurements to \p output_a */ +template +void nano::timer::stop (std::string & output_a) +{ + std::ostringstream stream; + stop (stream); + output_a = stream.str (); +} + +/** Print measurements to the \p stream_a */ +template +void nano::timer::print (std::ostream & stream_a) +{ + if (ticks >= minimum) + { + // Print cumulative children first. Non-cumulative children prints directly. + for (auto & child : children) + { + if (child.measurements > 0) + { + child.print (stream_a); + } + } + + auto current_parent = parent; + while (current_parent) + { + stream_a << parent->desc << "."; + current_parent = current_parent->parent; + } + + stream_a << desc << ": " << ticks.count () << ' ' << unit (); + if (measurements > 0) + { + stream_a << " (" << measurements << " measurements, " << std::setprecision (2) << std::fixed << static_cast (ticks.count ()) / static_cast (measurements) << ' ' << unit () << " avg)"; + } + stream_a << std::endl; + } +} + +/** Returns the SI unit string */ +template +std::string nano::timer::unit () const +{ + return typed_unit (); +} + +template +nano::timer_state nano::timer::current_state () const +{ + return state; +} + +// Explicitly instantiate all realistically used timers +template class nano::timer; +template class nano::timer; +template class nano::timer; +template class nano::timer; +template class nano::timer; +template class nano::timer; +template class nano::timer; +template class nano::timer; diff --git a/nano/lib/timer.hpp b/nano/lib/timer.hpp index 68790d13..6335f133 100644 --- a/nano/lib/timer.hpp +++ b/nano/lib/timer.hpp @@ -1,10 +1,7 @@ #pragma once -#include #include -#include -#include -#include +#include #include #include @@ -22,179 +19,25 @@ class timer { public: timer () = default; - - timer (nano::timer_state state_a, std::string description_a = "timer") : - desc (description_a) - { - if (state_a == nano::timer_state::started) - { - start (); - } - } - - timer (std::string description_a) : - desc (description_a) - { - } - - timer (std::string description_a, timer * parent_a) : - parent (parent_a), - desc (description_a) - { - } - - /** Do not output if measured time is below the time units threshold in \p minimum_a */ - timer & set_minimum (UNIT minimum_a) - { - minimum = minimum_a; - return *this; - } - - /** - * Create a child timer without starting it. - * Since the timing API needs to have low overhead, this function - * does not check if a timer with the same name already exists. - */ - timer & child (std::string description_a = "child timer") - { - children.emplace_back (description_a, this); - return children.back (); - } - - /** Create and start a child timer */ - timer & start_child (std::string description_a = "child timer") - { - auto & child_timer = child (description_a); - child_timer.start (); - return child_timer; - } - - /** Start the timer. This will assert if the timer is already started. */ - void start () - { - assert (state == nano::timer_state::stopped); - state = nano::timer_state::started; - begin = CLOCK::now (); - } - - /** Restarts the timer */ - void restart () - { - state = nano::timer_state::started; - begin = CLOCK::now (); - ticks = UNIT::zero (); - measurements = 0; - } - - /** - * Stops the timer and increases the measurement count. A timer can be started and paused - * multiple times (e.g. in a loop). - * @return duration - */ - UNIT pause () - { - ++measurements; - return stop (); - } - - /** - * Stop timer - * @return duration - */ - UNIT stop () - { - assert (state == nano::timer_state::started); - state = nano::timer_state::stopped; - - auto end = CLOCK::now (); - ticks += std::chrono::duration_cast (end - begin); - return ticks; - } - - /** - * Return current units. - */ - UNIT value () - { - return ticks; - } - - /** Returns the duration in UNIT since the timer was last started. */ - UNIT since_start () const - { - auto end = CLOCK::now (); - return std::chrono::duration_cast (end - begin); - } - - /** Returns true if the timer was last started longer than \p duration_a units ago*/ - bool after_deadline (UNIT duration_a) - { - auto end = CLOCK::now (); - return std::chrono::duration_cast (end - begin) > duration_a; - } - - /** Returns true if the timer was last started shorter than \p duration_a units ago*/ - bool before_deadline (UNIT duration_a) - { - auto end = CLOCK::now (); - return std::chrono::duration_cast (end - begin) < duration_a; - } - - /** Stop timer and write measurements to \p output_a */ - void stop (std::string & output_a) - { - std::ostringstream stream; - stop (stream); - output_a = stream.str (); - } - - /** Stop timer and write measurements to \p stream_a */ - void stop (std::ostream & stream_a) - { - stop (); - print (stream_a); - } - - /** Print measurements to the \p stream_a */ - void print (std::ostream & stream_a) - { - if (ticks >= minimum) - { - // Print cumulative children first. Non-cumulative children prints directly. - for (auto & child : children) - { - if (child.measurements > 0) - { - child.print (stream_a); - } - } - - auto current_parent = parent; - while (current_parent) - { - stream_a << parent->desc << "."; - current_parent = current_parent->parent; - } - - stream_a << desc << ": " << ticks.count () << ' ' << unit (); - if (measurements > 0) - { - stream_a << " (" << measurements << " measurements, " << std::setprecision (2) << std::fixed << static_cast (ticks.count ()) / static_cast (measurements) << ' ' << unit () << " avg)"; - } - stream_a << std::endl; - } - } - - /** Returns the SI unit string */ - std::string unit () const - { - return typed_unit (); - } - - nano::timer_state current_state () const - { - return state; - } + timer (nano::timer_state state_a, std::string const & description_a = "timer"); + timer (std::string const & description_a); + timer (std::string const & description_a, timer * parent_a); + timer & set_minimum (UNIT minimum_a); + timer & child (std::string const & description_a = "child timer"); + timer & start_child (std::string const & description_a = "child timer"); + void start (); + void restart (); + UNIT pause (); + UNIT stop (); + UNIT value () const; + UNIT since_start () const; + bool after_deadline (UNIT duration_a); + bool before_deadline (UNIT duration_a); + void stop (std::ostream & stream_a); + void stop (std::string & output_a); + void print (std::ostream & stream_a); + std::string unit () const; + nano::timer_state current_state () const; private: timer * parent{ nullptr }; @@ -205,62 +48,5 @@ private: UNIT ticks{ 0 }; UNIT minimum{ UNIT::zero () }; unsigned measurements{ 0 }; - - template ::value> * = nullptr> - std::string typed_unit () const - { - return "nanoseconds"; - } - - template ::value> * = nullptr> - std::string typed_unit () const - { - return "microseconds"; - } - - template ::value> * = nullptr> - std::string typed_unit () const - { - return "milliseconds"; - } - - template ::value> * = nullptr> - std::string typed_unit () const - { - return "seconds"; - } - - template ::value> * = nullptr> - std::string typed_unit () const - { - return "minutes"; - } - - template ::value> * = nullptr> - std::string typed_unit () const - { - return "hours"; - } -}; - -/** - * The autotimer starts on construction, and stops and prints on destruction. - */ -template -class autotimer : public nano::timer -{ -public: - autotimer (std::string description_a, std::ostream & stream_a = std::cout) : - nano::timer (description_a), stream (stream_a) - { - nano::timer::start (); - } - ~autotimer () - { - nano::timer::stop (stream); - } - -private: - std::ostream & stream; }; } diff --git a/nano/lib/tomlconfig.cpp b/nano/lib/tomlconfig.cpp new file mode 100644 index 00000000..1ee90e1c --- /dev/null +++ b/nano/lib/tomlconfig.cpp @@ -0,0 +1,385 @@ +#include +#include + +#include + +nano::tomlconfig::tomlconfig () : +tree (cpptoml::make_table ()) +{ + error = std::make_shared (); +} + +nano::tomlconfig::tomlconfig (std::shared_ptr const & tree_a, std::shared_ptr const & error_a) : +nano::configbase (error_a), tree (tree_a) +{ + if (!error) + { + error = std::make_shared (); + } +} + +void nano::tomlconfig::doc (std::string const & key, std::string const & doc) +{ + tree->document (key, doc); +} + +/** + * Reads a json object from the stream + * @return nano::error&, including a descriptive error message if the config file is malformed. + */ +nano::error & nano::tomlconfig::read (boost::filesystem::path const & path_a) +{ + std::stringstream stream_override_empty; + stream_override_empty << std::endl; + return read (stream_override_empty, path_a); +} + +nano::error & nano::tomlconfig::read (std::istream & stream_overrides, boost::filesystem::path const & path_a) +{ + std::fstream stream; + open_or_create (stream, path_a.string ()); + if (!stream.fail ()) + { + try + { + read (stream_overrides, stream); + } + catch (std::runtime_error const & ex) + { + auto pos (stream.tellg ()); + if (pos != std::streampos (0)) + { + *error = ex; + } + } + stream.close (); + } + return *error; +} + +/** Read from two streams where keys in the first will take precedence over those in the second stream. */ +void nano::tomlconfig::read (std::istream & stream_first_a, std::istream & stream_second_a) +{ + tree = cpptoml::parse_base_and_override_files (stream_first_a, stream_second_a, cpptoml::parser::merge_type::ignore, true); +} + +void nano::tomlconfig::read (std::istream & stream_a) +{ + std::stringstream stream_override_empty; + stream_override_empty << std::endl; + tree = cpptoml::parse_base_and_override_files (stream_override_empty, stream_a, cpptoml::parser::merge_type::ignore, true); +} + +void nano::tomlconfig::write (boost::filesystem::path const & path_a) +{ + std::fstream stream; + open_or_create (stream, path_a.string ()); + write (stream); +} + +void nano::tomlconfig::write (std::ostream & stream_a) const +{ + cpptoml::toml_writer writer{ stream_a, "" }; + tree->accept (writer); +} + +/** Open configuration file, create if necessary */ +void nano::tomlconfig::open_or_create (std::fstream & stream_a, std::string const & path_a) +{ + if (!boost::filesystem::exists (path_a)) + { + // Create temp stream to first create the file + std::ofstream stream (path_a); + + // Set permissions before opening otherwise Windows only has read permissions + nano::set_secure_perm_file (path_a); + } + + stream_a.open (path_a); +} + +/** Returns the table managed by this instance */ +std::shared_ptr nano::tomlconfig::get_tree () +{ + return tree; +} + +/** Returns true if the toml table is empty */ +bool nano::tomlconfig::empty () const +{ + return tree->empty (); +} + +boost::optional nano::tomlconfig::get_optional_child (std::string const & key_a) +{ + boost::optional child_config; + if (tree->contains (key_a)) + { + return tomlconfig (tree->get_table (key_a), error); + } + return child_config; +} + +nano::tomlconfig nano::tomlconfig::get_required_child (std::string const & key_a) +{ + if (!tree->contains (key_a)) + { + *error = nano::error_config::missing_value; + error->set_message ("Missing configuration node: " + key_a); + return *this; + } + else + { + return tomlconfig (tree->get_table (key_a), error); + } +} + +nano::tomlconfig & nano::tomlconfig::put_child (std::string const & key_a, nano::tomlconfig & conf_a) +{ + tree->insert (key_a, conf_a.get_tree ()); + return *this; +} + +nano::tomlconfig & nano::tomlconfig::replace_child (std::string const & key_a, nano::tomlconfig & conf_a) +{ + tree->erase (key_a); + put_child (key_a, conf_a); + return *this; +} + +/** Returns true if \p key_a is present */ +bool nano::tomlconfig::has_key (std::string const & key_a) +{ + return tree->contains (key_a); +} + +/** Erase the property of given key */ +nano::tomlconfig & nano::tomlconfig::erase (std::string const & key_a) +{ + tree->erase (key_a); + return *this; +} + +std::shared_ptr nano::tomlconfig::create_array (std::string const & key, boost::optional documentation_a) +{ + if (!has_key (key)) + { + auto arr = cpptoml::make_array (); + tree->insert (key, arr); + if (documentation_a) + { + doc (key, *documentation_a); + } + } + + return tree->get_qualified (key)->as_array (); +} + +/** + * Erase keys whose values are equal to the one in \p defaults + */ +void nano::tomlconfig::erase_default_values (tomlconfig & defaults_a) +{ + std::shared_ptr clone = std::dynamic_pointer_cast (tree->clone ()); + tomlconfig self (clone); + + // The toml library doesn't offer a general way to compare values, so let the diff run on a stringified parse + std::stringstream ss_self; + write (ss_self); + self.read (ss_self); + + tomlconfig defaults_l; + std::stringstream ss; + defaults_a.write (ss); + defaults_l.read (ss); + + erase_defaults (defaults_l.get_tree (), self.get_tree (), get_tree ()); +} + +std::string nano::tomlconfig::to_string () +{ + std::stringstream ss; + cpptoml::toml_writer writer{ ss, "" }; + tree->accept (writer); + return ss.str (); +} + +std::string nano::tomlconfig::to_string_commented_entries () +{ + std::stringstream ss, ss_processed; + cpptoml::toml_writer writer{ ss, "" }; + tree->accept (writer); + std::string line; + while (std::getline (ss, line, '\n')) + { + if (!line.empty () && line[0] != '#' && line[0] != '[') + { + line = "#" + line; + } + ss_processed << line << std::endl; + } + return ss_processed.str (); +} + +// boost's lexical cast doesn't handle (u)int8_t +nano::tomlconfig & nano::tomlconfig::get_config (bool optional, std::string const & key, uint8_t & target, uint8_t default_value) +{ + try + { + if (tree->contains_qualified (key)) + { + int64_t tmp; + auto val (tree->get_qualified_as (key)); + if (!boost::conversion::try_lexical_convert (*val, tmp) || tmp < 0 || tmp > 255) + { + conditionally_set_error (nano::error_config::invalid_value, optional, key); + } + else + { + target = static_cast (tmp); + } + } + else if (!optional) + { + conditionally_set_error (nano::error_config::missing_value, optional, key); + } + else + { + target = default_value; + } + } + catch (std::runtime_error & ex) + { + conditionally_set_error (ex, optional, key); + } + + return *this; +} + +nano::tomlconfig & nano::tomlconfig::get_config (bool optional, std::string const & key, bool & target, bool default_value) +{ + auto bool_conv = [this, &target, &key, optional](std::string val) { + if (val == "true") + { + target = true; + } + else if (val == "false") + { + target = false; + } + else if (!*error) + { + conditionally_set_error (nano::error_config::invalid_value, optional, key); + } + }; + try + { + if (tree->contains_qualified (key)) + { + auto val (tree->get_qualified_as (key)); + bool_conv (*val); + } + else if (!optional) + { + conditionally_set_error (nano::error_config::missing_value, optional, key); + } + else + { + target = default_value; + } + } + catch (std::runtime_error & ex) + { + conditionally_set_error (ex, optional, key); + } + return *this; +} + +/** Compare two stringified configs, remove keys where values are equal */ +void nano::tomlconfig::erase_defaults (std::shared_ptr base, std::shared_ptr other, std::shared_ptr update_target) +{ + std::vector erased; + assert (other != nullptr); + for (auto & item : *other) + { + std::string const & key = item.first; + if (other->contains (key) && base->contains (key)) + { + auto value = item.second; + if (value->is_table ()) + { + auto child_base = base->get_table (key); + auto child_other = other->get_table (key); + auto child_target = update_target->get_table (key); + erase_defaults (child_base, child_other, child_target); + if (child_target->empty ()) + { + erased.push_back (key); + } + } + else if (value->is_array ()) + { + auto arr_other = other->get_array (key)->get (); + auto arr_base = base->get_array (key)->get (); + + if (arr_other.size () == arr_base.size ()) + { + bool equal = std::equal (arr_other.begin (), arr_other.end (), arr_base.begin (), + [](auto const & item1, auto const & item2) -> bool { + return (item1->template as ()->get () == item2->template as ()->get ()); + }); + + if (equal) + { + erased.push_back (key); + } + } + } + else if (value->is_value ()) + { + auto val_other = std::dynamic_pointer_cast> (other->get (key)); + auto val_base = std::dynamic_pointer_cast> (base->get (key)); + + if (val_other->get () == val_base->get ()) + { + erased.push_back (key); + } + } + } + } + for (auto & key : erased) + { + update_target->erase (key); + } +} + +nano::tomlconfig & nano::tomlconfig::get_config (bool optional, std::string key, boost::asio::ip::address_v6 & target, boost::asio::ip::address_v6 const & default_value) +{ + try + { + if (tree->contains_qualified (key)) + { + auto address_l (tree->get_qualified_as (key)); + boost::system::error_code bec; + target = boost::asio::ip::make_address_v6 (address_l.value_or (""), bec); + if (bec) + { + conditionally_set_error (nano::error_config::invalid_value, optional, key); + } + } + else if (!optional) + { + conditionally_set_error (nano::error_config::missing_value, optional, key); + } + else + { + target = default_value; + } + } + catch (std::runtime_error & ex) + { + conditionally_set_error (ex, optional, key); + } + + return *this; +} \ No newline at end of file diff --git a/nano/lib/tomlconfig.hpp b/nano/lib/tomlconfig.hpp index 8e610929..0bfac87e 100644 --- a/nano/lib/tomlconfig.hpp +++ b/nano/lib/tomlconfig.hpp @@ -1,169 +1,55 @@ #pragma once -#include #include -#include #include -#include +#include #include #include -#include -#include -#include - #include +namespace boost +{ +namespace asio +{ + namespace ip + { + class address_v6; + } +} +} + namespace nano { +class error; + /** Manages a table in a toml configuration table hierarchy */ class tomlconfig : public nano::configbase { public: - tomlconfig () : - tree (cpptoml::make_table ()) - { - error = std::make_shared (); - } - - tomlconfig (std::shared_ptr const & tree_a, std::shared_ptr const & error_a = nullptr) : - nano::configbase (error_a), tree (tree_a) - { - if (!error) - { - error = std::make_shared (); - } - } - - void doc (std::string const & key, std::string const & doc) - { - tree->document (key, doc); - } - - /** - * Reads a json object from the stream - * @return nano::error&, including a descriptive error message if the config file is malformed. - */ - nano::error & read (boost::filesystem::path const & path_a) - { - std::stringstream stream_override_empty; - stream_override_empty << std::endl; - return read (stream_override_empty, path_a); - } - - nano::error & read (std::istream & stream_overrides, boost::filesystem::path const & path_a) - { - std::fstream stream; - open_or_create (stream, path_a.string ()); - if (!stream.fail ()) - { - try - { - read (stream_overrides, stream); - } - catch (std::runtime_error const & ex) - { - auto pos (stream.tellg ()); - if (pos != std::streampos (0)) - { - *error = ex; - } - } - stream.close (); - } - return *error; - } - - /** Read from two streams where keys in the first will take precedence over those in the second stream. */ - void read (std::istream & stream_first_a, std::istream & stream_second_a) - { - tree = cpptoml::parse_base_and_override_files (stream_first_a, stream_second_a, cpptoml::parser::merge_type::ignore, true); - } - - void read (std::istream & stream_a) - { - std::stringstream stream_override_empty; - stream_override_empty << std::endl; - tree = cpptoml::parse_base_and_override_files (stream_override_empty, stream_a, cpptoml::parser::merge_type::ignore, true); - } - - void write (boost::filesystem::path const & path_a) - { - std::fstream stream; - open_or_create (stream, path_a.string ()); - write (stream); - } - - void write (std::ostream & stream_a) const - { - cpptoml::toml_writer writer{ stream_a, "" }; - tree->accept (writer); - } - - /** Open configuration file, create if necessary */ - void open_or_create (std::fstream & stream_a, std::string const & path_a) - { - if (!boost::filesystem::exists (path_a)) - { - // Create temp stream to first create the file - std::ofstream stream (path_a); - - // Set permissions before opening otherwise Windows only has read permissions - nano::set_secure_perm_file (path_a); - } - - stream_a.open (path_a); - } - - /** Returns the table managed by this instance */ - std::shared_ptr get_tree () - { - return tree; - } - - /** Returns true if the toml table is empty */ - bool empty () const - { - return tree->empty (); - } - - boost::optional get_optional_child (std::string const & key_a) - { - boost::optional child_config; - if (tree->contains (key_a)) - { - return tomlconfig (tree->get_table (key_a), error); - } - return child_config; - } - - tomlconfig get_required_child (std::string const & key_a) - { - if (!tree->contains (key_a)) - { - *error = nano::error_config::missing_value; - error->set_message ("Missing configuration node: " + key_a); - return *this; - } - else - { - return tomlconfig (tree->get_table (key_a), error); - } - } - - tomlconfig & put_child (std::string const & key_a, nano::tomlconfig & conf_a) - { - tree->insert (key_a, conf_a.get_tree ()); - return *this; - } - - tomlconfig & replace_child (std::string const & key_a, nano::tomlconfig & conf_a) - { - tree->erase (key_a); - put_child (key_a, conf_a); - return *this; - } + tomlconfig (); + tomlconfig (std::shared_ptr const & tree_a, std::shared_ptr const & error_a = nullptr); + void doc (std::string const & key, std::string const & doc); + nano::error & read (boost::filesystem::path const & path_a); + nano::error & read (std::istream & stream_overrides, boost::filesystem::path const & path_a); + void read (std::istream & stream_first_a, std::istream & stream_second_a); + void read (std::istream & stream_a); + void write (boost::filesystem::path const & path_a); + void write (std::ostream & stream_a) const; + void open_or_create (std::fstream & stream_a, std::string const & path_a); + std::shared_ptr get_tree (); + bool empty () const; + boost::optional get_optional_child (std::string const & key_a); + tomlconfig get_required_child (std::string const & key_a); + tomlconfig & put_child (std::string const & key_a, nano::tomlconfig & conf_a); + tomlconfig & replace_child (std::string const & key_a, nano::tomlconfig & conf_a); + bool has_key (std::string const & key_a); + tomlconfig & erase (std::string const & key_a); + std::shared_ptr create_array (std::string const & key, boost::optional documentation_a); + void erase_default_values (tomlconfig & defaults_a); + std::string to_string (); + std::string to_string_commented_entries (); /** Set value for the given key. Any existing value will be overwritten. */ template @@ -177,19 +63,6 @@ public: return *this; } - /** Returns true if \p key_a is present */ - bool has_key (std::string const & key_a) - { - return tree->contains (key_a); - } - - /** Erase the property of given key */ - tomlconfig & erase (std::string const & key_a) - { - tree->erase (key_a); - return *this; - } - /** * Push array element * @param key Array element key. Qualified (dotted) keys are not supported for arrays so this must be called on the correct tomlconfig node. @@ -207,21 +80,6 @@ public: return *this; } - auto create_array (std::string const & key, boost::optional documentation_a) - { - if (!has_key (key)) - { - auto arr = cpptoml::make_array (); - tree->insert (key, arr); - if (documentation_a) - { - doc (key, *documentation_a); - } - } - - return tree->get_qualified (key)->as_array (); - } - /** * Iterate array entries. * @param key Array element key. Qualified (dotted) keys are not supported for arrays so this must be called on the correct tomlconfig node. @@ -248,7 +106,7 @@ public: template tomlconfig & get_optional (std::string const & key, T & target, T default_value) { - get_config (true, key, target, default_value); + get_config (true, key, target, default_value); return *this; } @@ -259,7 +117,7 @@ public: template tomlconfig & get_optional (std::string const & key, T & target) { - get_config (true, key, target, target); + get_config (true, key, target, target); return *this; } @@ -271,7 +129,7 @@ public: if (has_key (key)) { T target{}; - get_config (true, key, target, target); + get_config (true, key, target, target); res = target; } return res; @@ -281,7 +139,7 @@ public: template tomlconfig & get (std::string const & key, T & target) { - get_config (true, key, target, target); + get_config (true, key, target, target); return *this; } @@ -292,7 +150,7 @@ public: T get (std::string const & key) { T target{}; - get_config (true, key, target, target); + get_config (true, key, target, target); return target; } @@ -303,54 +161,15 @@ public: template tomlconfig & get_required (std::string const & key, T & target) { - get_config (false, key, target); + get_config (false, key, target); return *this; } - /** - * Erase keys whose values are equal to the one in \p defaults - */ - void erase_default_values (tomlconfig & defaults_a) + template + tomlconfig & get_required (std::string const & key, T & target, T const & default_value) { - std::shared_ptr clone = std::dynamic_pointer_cast (tree->clone ()); - tomlconfig self (clone); - - // The toml library doesn't offer a general way to compare values, so let the diff run on a stringified parse - std::stringstream ss_self; - write (ss_self); - self.read (ss_self); - - tomlconfig defaults_l; - std::stringstream ss; - defaults_a.write (ss); - defaults_l.read (ss); - - erase_defaults (defaults_l.get_tree (), self.get_tree (), get_tree ()); - } - - std::string to_string () - { - std::stringstream ss; - cpptoml::toml_writer writer{ ss, "" }; - tree->accept (writer); - return ss.str (); - } - - std::string to_string_commented_entries () - { - std::stringstream ss, ss_processed; - cpptoml::toml_writer writer{ ss, "" }; - tree->accept (writer); - std::string line; - while (std::getline (ss, line, '\n')) - { - if (!line.empty () && line[0] != '#' && line[0] != '[') - { - line = "#" + line; - } - ss_processed << line << std::endl; - } - return ss_processed.str (); + get_config (false, key, target, default_value); + return *this; } protected: @@ -384,174 +203,15 @@ protected: return *this; } - // boost's lexical cast doesn't handle (u)int8_t - template ::value>> - tomlconfig & get_config (bool optional, std::string const & key, uint8_t & target, uint8_t default_value = T ()) - { - try - { - if (tree->contains_qualified (key)) - { - int64_t tmp; - auto val (tree->get_qualified_as (key)); - if (!boost::conversion::try_lexical_convert (*val, tmp) || tmp < 0 || tmp > 255) - { - conditionally_set_error (nano::error_config::invalid_value, optional, key); - } - else - { - target = static_cast (tmp); - } - } - else if (!optional) - { - conditionally_set_error (nano::error_config::missing_value, optional, key); - } - else - { - target = default_value; - } - } - catch (std::runtime_error & ex) - { - conditionally_set_error (ex, optional, key); - } - - return *this; - } - - template ::value>> - tomlconfig & get_config (bool optional, std::string const & key, bool & target, bool default_value = false) - { - auto bool_conv = [this, &target, &key, optional](std::string val) { - if (val == "true") - { - target = true; - } - else if (val == "false") - { - target = false; - } - else if (!*error) - { - conditionally_set_error (nano::error_config::invalid_value, optional, key); - } - }; - try - { - if (tree->contains_qualified (key)) - { - auto val (tree->get_qualified_as (key)); - bool_conv (*val); - } - else if (!optional) - { - conditionally_set_error (nano::error_config::missing_value, optional, key); - } - else - { - target = default_value; - } - } - catch (std::runtime_error & ex) - { - conditionally_set_error (ex, optional, key); - } - return *this; - } - - template ::value>> - tomlconfig & get_config (bool optional, std::string key, boost::asio::ip::address_v6 & target, boost::asio::ip::address_v6 default_value = T ()) - { - try - { - if (tree->contains_qualified (key)) - { - auto address_l (tree->get_qualified_as (key)); - boost::system::error_code bec; - target = boost::asio::ip::address_v6::from_string (address_l.value_or (""), bec); - if (bec) - { - conditionally_set_error (nano::error_config::invalid_value, optional, key); - } - } - else if (!optional) - { - conditionally_set_error (nano::error_config::missing_value, optional, key); - } - else - { - target = default_value; - } - } - catch (std::runtime_error & ex) - { - conditionally_set_error (ex, optional, key); - } - - return *this; - } + tomlconfig & get_config (bool optional, std::string const & key, uint8_t & target, uint8_t default_value = uint8_t ()); + tomlconfig & get_config (bool optional, std::string const & key, bool & target, bool default_value = false); + tomlconfig & get_config (bool optional, std::string key, boost::asio::ip::address_v6 & target, boost::asio::ip::address_v6 const & default_value); private: /** The config node being managed */ std::shared_ptr tree; /** Compare two stringified configs, remove keys where values are equal */ - void erase_defaults (std::shared_ptr base, std::shared_ptr other, std::shared_ptr update_target) - { - std::vector erased; - assert (other != nullptr); - for (auto & item : *other) - { - std::string const & key = item.first; - if (other->contains (key) && base->contains (key)) - { - auto value = item.second; - if (value->is_table ()) - { - auto child_base = base->get_table (key); - auto child_other = other->get_table (key); - auto child_target = update_target->get_table (key); - erase_defaults (child_base, child_other, child_target); - if (child_target->empty ()) - { - erased.push_back (key); - } - } - else if (value->is_array ()) - { - auto arr_other = other->get_array (key)->get (); - auto arr_base = base->get_array (key)->get (); - - if (arr_other.size () == arr_base.size ()) - { - bool equal = std::equal (arr_other.begin (), arr_other.end (), arr_base.begin (), - [](auto const & item1, auto const & item2) -> bool { - return (item1->template as ()->get () == item2->template as ()->get ()); - }); - - if (equal) - { - erased.push_back (key); - } - } - } - else if (value->is_value ()) - { - auto val_other = std::dynamic_pointer_cast> (other->get (key)); - auto val_base = std::dynamic_pointer_cast> (base->get (key)); - - if (val_other->get () == val_base->get ()) - { - erased.push_back (key); - } - } - } - } - for (auto & key : erased) - { - update_target->erase (key); - } - } + void erase_defaults (std::shared_ptr base, std::shared_ptr other, std::shared_ptr update_target); }; } diff --git a/nano/lib/utility.cpp b/nano/lib/utility.cpp index ede99219..83bae3e4 100644 --- a/nano/lib/utility.cpp +++ b/nano/lib/utility.cpp @@ -1,8 +1,10 @@ #include #include +#include #include +#include // Some builds (mac) fail due to "Boost.Stacktrace requires `_Unwind_Backtrace` function". #ifndef _WIN32 @@ -79,243 +81,6 @@ std::string generate_stacktrace () ss << stacktrace; return ss.str (); } - -namespace thread_role -{ - /* - * nano::thread_role namespace - * - * Manage thread role - */ - static thread_local nano::thread_role::name current_thread_role = nano::thread_role::name::unknown; - nano::thread_role::name get () - { - return current_thread_role; - } - - std::string get_string (nano::thread_role::name role) - { - std::string thread_role_name_string; - - switch (role) - { - case nano::thread_role::name::unknown: - thread_role_name_string = ""; - break; - case nano::thread_role::name::io: - thread_role_name_string = "I/O"; - break; - case nano::thread_role::name::work: - thread_role_name_string = "Work pool"; - break; - case nano::thread_role::name::packet_processing: - thread_role_name_string = "Pkt processing"; - break; - case nano::thread_role::name::alarm: - thread_role_name_string = "Alarm"; - break; - case nano::thread_role::name::vote_processing: - thread_role_name_string = "Vote processing"; - break; - case nano::thread_role::name::block_processing: - thread_role_name_string = "Blck processing"; - break; - case nano::thread_role::name::request_loop: - thread_role_name_string = "Request loop"; - break; - case nano::thread_role::name::wallet_actions: - thread_role_name_string = "Wallet actions"; - break; - case nano::thread_role::name::work_watcher: - thread_role_name_string = "Work watcher"; - break; - case nano::thread_role::name::bootstrap_initiator: - thread_role_name_string = "Bootstrap init"; - break; - case nano::thread_role::name::voting: - thread_role_name_string = "Voting"; - break; - case nano::thread_role::name::signature_checking: - thread_role_name_string = "Signature check"; - break; - case nano::thread_role::name::rpc_request_processor: - thread_role_name_string = "RPC processor"; - break; - case nano::thread_role::name::rpc_process_container: - thread_role_name_string = "RPC process"; - break; - case nano::thread_role::name::confirmation_height_processing: - thread_role_name_string = "Conf height"; - break; - case nano::thread_role::name::worker: - thread_role_name_string = "Worker"; - break; - } - - /* - * We want to constrain the thread names to 15 - * characters, since this is the smallest maximum - * length supported by the platforms we support - * (specifically, Linux) - */ - assert (thread_role_name_string.size () < 16); - return (thread_role_name_string); - } - - std::string get_string () - { - return get_string (current_thread_role); - } - - void set (nano::thread_role::name role) - { - auto thread_role_name_string (get_string (role)); - - nano::thread_role::set_os_name (thread_role_name_string); - - nano::thread_role::current_thread_role = role; - } -} -} - -void nano::thread_attributes::set (boost::thread::attributes & attrs) -{ - auto attrs_l (&attrs); - attrs_l->set_stack_size (8000000); //8MB -} - -nano::thread_runner::thread_runner (boost::asio::io_context & io_ctx_a, unsigned service_threads_a) : -io_guard (boost::asio::make_work_guard (io_ctx_a)) -{ - boost::thread::attributes attrs; - nano::thread_attributes::set (attrs); - for (auto i (0u); i < service_threads_a; ++i) - { - threads.push_back (boost::thread (attrs, [&io_ctx_a]() { - nano::thread_role::set (nano::thread_role::name::io); - try - { - io_ctx_a.run (); - } - catch (std::exception const & ex) - { - std::cerr << ex.what () << std::endl; -#ifndef NDEBUG - throw; -#endif - } - catch (...) - { -#ifndef NDEBUG - /* - * In a release build, catch and swallow the - * io_context exception, in debug mode pass it - * on - */ - throw; -#endif - } - })); - } -} - -nano::thread_runner::~thread_runner () -{ - join (); -} - -void nano::thread_runner::join () -{ - io_guard.reset (); - for (auto & i : threads) - { - if (i.joinable ()) - { - i.join (); - } - } -} - -void nano::thread_runner::stop_event_processing () -{ - io_guard.get_executor ().context ().stop (); -} - -nano::worker::worker () : -thread ([this]() { - nano::thread_role::set (nano::thread_role::name::worker); - this->run (); -}) -{ -} - -void nano::worker::run () -{ - nano::unique_lock lk (mutex); - while (!stopped) - { - if (!queue.empty ()) - { - auto func = queue.front (); - queue.pop_front (); - lk.unlock (); - func (); - // So that we reduce locking for anything being pushed as that will - // most likely be on an io-thread - std::this_thread::yield (); - lk.lock (); - } - else - { - cv.wait (lk); - } - } -} - -nano::worker::~worker () -{ - stop (); -} - -void nano::worker::push_task (std::function func_a) -{ - { - nano::lock_guard guard (mutex); - if (!stopped) - { - queue.emplace_back (func_a); - } - } - - cv.notify_one (); -} - -void nano::worker::stop () -{ - { - nano::unique_lock lk (mutex); - stopped = true; - queue.clear (); - } - cv.notify_one (); - if (thread.joinable ()) - { - thread.join (); - } -} - -std::unique_ptr nano::collect_seq_con_info (nano::worker & worker, const std::string & name) -{ - auto composite = std::make_unique (name); - - size_t count = 0; - { - nano::lock_guard guard (worker.mutex); - count = worker.queue.size (); - } - auto sizeof_element = sizeof (decltype (worker.queue)::value_type); - composite->add_component (std::make_unique (nano::seq_con_info{ "queue", count, sizeof_element })); - return composite; } void nano::remove_all_files_in_dir (boost::filesystem::path const & dir) diff --git a/nano/lib/utility.hpp b/nano/lib/utility.hpp index 10e49b9d..d3b0520b 100644 --- a/nano/lib/utility.hpp +++ b/nano/lib/utility.hpp @@ -1,17 +1,24 @@ #pragma once -#include #include -#include -#include -#include - #include #include -#include #include +namespace boost +{ +namespace filesystem +{ + class path; +} + +namespace system +{ + class error_code; +} +} + namespace nano { /* These containers are used to collect information about sequence containers. @@ -94,92 +101,6 @@ void dump_crash_stacktrace (); */ std::string generate_stacktrace (); -/* - * Functions for understanding the role of the current thread - */ -namespace thread_role -{ - enum class name - { - unknown, - io, - work, - packet_processing, - alarm, - vote_processing, - block_processing, - request_loop, - wallet_actions, - bootstrap_initiator, - voting, - signature_checking, - rpc_request_processor, - rpc_process_container, - work_watcher, - confirmation_height_processing, - worker - }; - /* - * Get/Set the identifier for the current thread - */ - nano::thread_role::name get (); - void set (nano::thread_role::name); - - /* - * Get the thread name as a string from enum - */ - std::string get_string (nano::thread_role::name); - - /* - * Get the current thread's role as a string - */ - std::string get_string (); - - /* - * Internal only, should not be called directly - */ - void set_os_name (std::string const &); -} - -namespace thread_attributes -{ - void set (boost::thread::attributes &); -} - -class thread_runner final -{ -public: - thread_runner (boost::asio::io_context &, unsigned); - ~thread_runner (); - /** Tells the IO context to stop processing events.*/ - void stop_event_processing (); - /** Wait for IO threads to complete */ - void join (); - std::vector threads; - boost::asio::executor_work_guard io_guard; -}; - -class worker final -{ -public: - worker (); - ~worker (); - void run (); - void push_task (std::function func); - void stop (); - -private: - nano::condition_variable cv; - std::deque> queue; - std::mutex mutex; - bool stopped{ false }; - std::thread thread; - - friend std::unique_ptr collect_seq_con_info (worker &, const std::string &); -}; - -std::unique_ptr collect_seq_con_info (worker & worker, const std::string & name); - /** * Returns seconds passed since unix epoch (posix time) */ diff --git a/nano/lib/work.cpp b/nano/lib/work.cpp index d78e2aec..ffe350b5 100644 --- a/nano/lib/work.cpp +++ b/nano/lib/work.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include diff --git a/nano/lib/work.hpp b/nano/lib/work.hpp index 7c61bda4..7ed722d9 100644 --- a/nano/lib/work.hpp +++ b/nano/lib/work.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include @@ -8,13 +9,12 @@ #include #include -#include #include -#include namespace nano { class block; + bool work_validate (nano::root const &, uint64_t, uint64_t * = nullptr); bool work_validate (nano::block const &, uint64_t * = nullptr); uint64_t work_value (nano::root const &, uint64_t); diff --git a/nano/lib/worker.cpp b/nano/lib/worker.cpp new file mode 100644 index 00000000..12f57c64 --- /dev/null +++ b/nano/lib/worker.cpp @@ -0,0 +1,79 @@ +#include +#include + +nano::worker::worker () : +thread ([this]() { + nano::thread_role::set (nano::thread_role::name::worker); + this->run (); +}) +{ +} + +void nano::worker::run () +{ + nano::unique_lock lk (mutex); + while (!stopped) + { + if (!queue.empty ()) + { + auto func = queue.front (); + queue.pop_front (); + lk.unlock (); + func (); + // So that we reduce locking for anything being pushed as that will + // most likely be on an io-thread + std::this_thread::yield (); + lk.lock (); + } + else + { + cv.wait (lk); + } + } +} + +nano::worker::~worker () +{ + stop (); +} + +void nano::worker::push_task (std::function func_a) +{ + { + nano::lock_guard guard (mutex); + if (!stopped) + { + queue.emplace_back (func_a); + } + } + + cv.notify_one (); +} + +void nano::worker::stop () +{ + { + nano::unique_lock lk (mutex); + stopped = true; + queue.clear (); + } + cv.notify_one (); + if (thread.joinable ()) + { + thread.join (); + } +} + +std::unique_ptr nano::collect_seq_con_info (nano::worker & worker, const std::string & name) +{ + auto composite = std::make_unique (name); + + size_t count = 0; + { + nano::lock_guard guard (worker.mutex); + count = worker.queue.size (); + } + auto sizeof_element = sizeof (decltype (worker.queue)::value_type); + composite->add_component (std::make_unique (nano::seq_con_info{ "queue", count, sizeof_element })); + return composite; +} diff --git a/nano/lib/worker.hpp b/nano/lib/worker.hpp new file mode 100644 index 00000000..a639db27 --- /dev/null +++ b/nano/lib/worker.hpp @@ -0,0 +1,33 @@ +#pragma once + +#include +#include + +#include +#include +#include +#include + +namespace nano +{ +class worker final +{ +public: + worker (); + ~worker (); + void run (); + void push_task (std::function func); + void stop (); + +private: + nano::condition_variable cv; + std::deque> queue; + std::mutex mutex; + bool stopped{ false }; + std::thread thread; + + friend std::unique_ptr collect_seq_con_info (worker &, const std::string &); +}; + +std::unique_ptr collect_seq_con_info (worker & worker, const std::string & name); +} \ No newline at end of file diff --git a/nano/load_test/entry.cpp b/nano/load_test/entry.cpp index 47247708..3380b1f5 100644 --- a/nano/load_test/entry.cpp +++ b/nano/load_test/entry.cpp @@ -1,7 +1,10 @@ -#include -#include -#include +#include +#include +#include +#include +#include #include +#include #include #include #include @@ -9,6 +12,7 @@ #include #include +#include #include #include diff --git a/nano/nano_node/daemon.cpp b/nano/nano_node/daemon.cpp index bbfc8126..191cebf8 100644 --- a/nano/nano_node/daemon.cpp +++ b/nano/nano_node/daemon.cpp @@ -1,4 +1,5 @@ -#include +#include +#include #include #include #include @@ -9,10 +10,7 @@ #include #include -#include - #include -#include #include namespace @@ -81,7 +79,6 @@ void nano_daemon::daemon::run (boost::filesystem::path const & data_path, nano:: } #if BOOST_PROCESS_SUPPORTED - auto network = node->network_params.network.get_current_network_as_string (); nano_pow_server_process = std::make_unique (config.pow_server.pow_server_path, "--config_path", data_path / "config-nano-pow-server.toml"); #else std::cerr << "nano_pow_server is configured to start as a child process, but this is not supported on this system. Disable startup and start the server manually." << std::endl; diff --git a/nano/nano_node/daemon.hpp b/nano/nano_node/daemon.hpp index 4301f7c3..acb09e85 100644 --- a/nano/nano_node/daemon.hpp +++ b/nano/nano_node/daemon.hpp @@ -1,4 +1,10 @@ -#include +namespace boost +{ +namespace filesystem +{ + class path; +} +} namespace nano { diff --git a/nano/nano_node/entry.cpp b/nano/nano_node/entry.cpp index 3b018610..116f78cb 100644 --- a/nano/nano_node/entry.cpp +++ b/nano/nano_node/entry.cpp @@ -5,9 +5,10 @@ #include #include #include -#include #include +#include +#include #include #include @@ -98,7 +99,7 @@ int main (int argc, char * const * argv) auto err (nano::network_constants::set_active_network (network->second.as ())); if (err) { - std::cerr << err.get_message () << std::endl; + std::cerr << nano::network_constants::active_network_err_msg << std::endl; std::exit (1); } } diff --git a/nano/nano_rpc/entry.cpp b/nano/nano_rpc/entry.cpp index 3613da00..fd2ad134 100644 --- a/nano/nano_rpc/entry.cpp +++ b/nano/nano_rpc/entry.cpp @@ -1,15 +1,13 @@ #include -#include +#include #include -#include #include #include #include #include -#include +#include -#include -#include +#include #include #include #include @@ -117,7 +115,7 @@ int main (int argc, char * const * argv) auto err (nano::network_constants::set_active_network (network->second.as ())); if (err) { - std::cerr << err.get_message () << std::endl; + std::cerr << nano::network_constants::active_network_err_msg << std::endl; std::exit (1); } } diff --git a/nano/nano_wallet/entry.cpp b/nano/nano_wallet/entry.cpp index 90d8b030..8e68ab49 100644 --- a/nano/nano_wallet/entry.cpp +++ b/nano/nano_wallet/entry.cpp @@ -1,7 +1,8 @@ -#include +#include #include #include #include +#include #include #include #include @@ -150,7 +151,6 @@ int run_wallet (QApplication & application, int argc, char * const * argv, boost } #if BOOST_PROCESS_SUPPORTED - auto network = node->network_params.network.get_current_network_as_string (); nano_pow_server_process = std::make_unique (config.pow_server.pow_server_path, "--config_path", data_path / "config-nano-pow-server.toml"); #else splash->hide (); @@ -269,7 +269,7 @@ int main (int argc, char * const * argv) auto err (nano::network_constants::set_active_network (network->second.as ())); if (err) { - show_error (err.get_message ()); + show_error (nano::network_constants::active_network_err_msg); std::exit (1); } } diff --git a/nano/node/CMakeLists.txt b/nano/node/CMakeLists.txt index e2c57a3b..66afee12 100644 --- a/nano/node/CMakeLists.txt +++ b/nano/node/CMakeLists.txt @@ -47,6 +47,8 @@ add_library (node daemonconfig.cpp distributed_work.hpp distributed_work.cpp + distributed_work_factory.hpp + distributed_work_factory.cpp election.hpp election.cpp gap_cache.hpp diff --git a/nano/node/active_transactions.cpp b/nano/node/active_transactions.cpp index 6e10f6a9..1cce71c6 100644 --- a/nano/node/active_transactions.cpp +++ b/nano/node/active_transactions.cpp @@ -1,7 +1,10 @@ +#include #include +#include #include -#include +#include +#include #include diff --git a/nano/node/active_transactions.hpp b/nano/node/active_transactions.hpp index f6fde3a3..4e4dcd81 100644 --- a/nano/node/active_transactions.hpp +++ b/nano/node/active_transactions.hpp @@ -1,7 +1,6 @@ #pragma once #include -#include #include #include #include @@ -12,17 +11,13 @@ #include #include #include -#include #include -#include #include #include #include #include #include -#include -#include #include #include @@ -31,8 +26,8 @@ namespace nano class node; class block; class block_sideband; -class vote; class election; +class vote; class transaction; class conflict_info final diff --git a/nano/node/blockprocessor.cpp b/nano/node/blockprocessor.cpp index d63991f5..25ee74ed 100644 --- a/nano/node/blockprocessor.cpp +++ b/nano/node/blockprocessor.cpp @@ -3,12 +3,14 @@ #include #include +#include + #include std::chrono::milliseconds constexpr nano::block_processor::confirmation_request_delay; nano::block_processor::block_processor (nano::node & node_a, nano::write_database_queue & write_database_queue_a) : -generator (node_a), +generator (node_a.config, node_a.store, node_a.wallets, node_a.vote_processor, node_a.votes_cache, node_a.network), stopped (false), active (false), next_log (std::chrono::steady_clock::now ()), diff --git a/nano/node/blockprocessor.hpp b/nano/node/blockprocessor.hpp index 49fc64dd..1c2b0fe1 100644 --- a/nano/node/blockprocessor.hpp +++ b/nano/node/blockprocessor.hpp @@ -7,7 +7,6 @@ #include #include #include -#include #include #include diff --git a/nano/node/bootstrap/bootstrap.cpp b/nano/node/bootstrap/bootstrap.cpp index dc2d1a86..eb77b9e3 100644 --- a/nano/node/bootstrap/bootstrap.cpp +++ b/nano/node/bootstrap/bootstrap.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -7,7 +8,7 @@ #include #include -#include +#include #include diff --git a/nano/node/bootstrap/bootstrap.hpp b/nano/node/bootstrap/bootstrap.hpp index eaf430bf..2af597ee 100644 --- a/nano/node/bootstrap/bootstrap.hpp +++ b/nano/node/bootstrap/bootstrap.hpp @@ -6,7 +6,6 @@ #include #include -#include #include #include #include @@ -17,7 +16,6 @@ #include #include #include -#include #include namespace nano diff --git a/nano/node/bootstrap/bootstrap_bulk_pull.cpp b/nano/node/bootstrap/bootstrap_bulk_pull.cpp index bff0c3ca..b762496f 100644 --- a/nano/node/bootstrap/bootstrap_bulk_pull.cpp +++ b/nano/node/bootstrap/bootstrap_bulk_pull.cpp @@ -3,6 +3,8 @@ #include #include +#include + nano::pull_info::pull_info (nano::hash_or_account const & account_or_head_a, nano::block_hash const & head_a, nano::block_hash const & end_a, count_t count_a, unsigned retry_limit_a) : account_or_head (account_or_head_a), head (head_a), diff --git a/nano/node/bootstrap/bootstrap_bulk_push.cpp b/nano/node/bootstrap/bootstrap_bulk_push.cpp index 435da4a0..95eb49b6 100644 --- a/nano/node/bootstrap/bootstrap_bulk_push.cpp +++ b/nano/node/bootstrap/bootstrap_bulk_push.cpp @@ -3,6 +3,8 @@ #include #include +#include + nano::bulk_push_client::bulk_push_client (std::shared_ptr const & connection_a) : connection (connection_a) { diff --git a/nano/node/bootstrap/bootstrap_bulk_push.hpp b/nano/node/bootstrap/bootstrap_bulk_push.hpp index ecf8541e..114a0235 100644 --- a/nano/node/bootstrap/bootstrap_bulk_push.hpp +++ b/nano/node/bootstrap/bootstrap_bulk_push.hpp @@ -1,7 +1,8 @@ #pragma once #include -#include + +#include namespace nano { diff --git a/nano/node/bootstrap/bootstrap_frontier.cpp b/nano/node/bootstrap/bootstrap_frontier.cpp index a5ff90ad..ad51fed1 100644 --- a/nano/node/bootstrap/bootstrap_frontier.cpp +++ b/nano/node/bootstrap/bootstrap_frontier.cpp @@ -3,6 +3,8 @@ #include #include +#include + constexpr double nano::bootstrap_limits::bootstrap_connection_warmup_time_sec; constexpr double nano::bootstrap_limits::bootstrap_minimum_elapsed_seconds_blockrate; constexpr double nano::bootstrap_limits::bootstrap_minimum_frontier_blocks_per_sec; diff --git a/nano/node/bootstrap/bootstrap_frontier.hpp b/nano/node/bootstrap/bootstrap_frontier.hpp index 82410224..b6b788d0 100644 --- a/nano/node/bootstrap/bootstrap_frontier.hpp +++ b/nano/node/bootstrap/bootstrap_frontier.hpp @@ -1,7 +1,9 @@ #pragma once #include -#include + +#include +#include namespace nano { diff --git a/nano/node/bootstrap/bootstrap_server.cpp b/nano/node/bootstrap/bootstrap_server.cpp index 4935ccf6..858ab000 100644 --- a/nano/node/bootstrap/bootstrap_server.cpp +++ b/nano/node/bootstrap/bootstrap_server.cpp @@ -1,7 +1,11 @@ +#include +#include #include #include #include +#include + nano::bootstrap_listener::bootstrap_listener (uint16_t port_a, nano::node & node_a) : node (node_a), port (port_a) diff --git a/nano/node/cli.cpp b/nano/node/cli.cpp index dadc00e0..436449ee 100644 --- a/nano/node/cli.cpp +++ b/nano/node/cli.cpp @@ -1,10 +1,11 @@ -#include #include #include #include #include #include +#include + namespace { void reset_confirmation_heights (nano::block_store & store); diff --git a/nano/node/common.cpp b/nano/node/common.cpp index 205b2acc..c5184a54 100644 --- a/nano/node/common.cpp +++ b/nano/node/common.cpp @@ -4,9 +4,11 @@ #include #include #include +#include #include #include +#include std::bitset<16> constexpr nano::message_header::block_type_mask; std::bitset<16> constexpr nano::message_header::count_mask; @@ -104,6 +106,19 @@ header (header_a) { } +std::shared_ptr> nano::message::to_bytes () const +{ + auto bytes = std::make_shared> (); + nano::vectorstream stream (*bytes); + serialize (stream); + return bytes; +} + +nano::shared_const_buffer nano::message::to_shared_const_buffer () const +{ + return shared_const_buffer (to_bytes ()); +} + nano::block_type nano::message_header::block_type () const { return static_cast (((extensions & block_type_mask) >> 8).to_ullong ()); @@ -1107,7 +1122,7 @@ bool nano::parse_address_port (std::string const & string, boost::asio::ip::addr if (!result) { boost::system::error_code ec; - auto address (boost::asio::ip::address_v6::from_string (string.substr (0, port_position), ec)); + auto address (boost::asio::ip::make_address_v6 (string.substr (0, port_position), ec)); if (!ec) { address_a = address; diff --git a/nano/node/common.hpp b/nano/node/common.hpp index f8cfff11..e3f4b48f 100644 --- a/nano/node/common.hpp +++ b/nano/node/common.hpp @@ -1,9 +1,9 @@ #pragma once -#include +#include +#include #include #include -#include #include #include @@ -217,17 +217,9 @@ public: virtual ~message () = default; virtual void serialize (nano::stream &) const = 0; virtual void visit (nano::message_visitor &) const = 0; - std::shared_ptr> to_bytes () const - { - auto bytes = std::make_shared> (); - nano::vectorstream stream (*bytes); - serialize (stream); - return bytes; - } - nano::shared_const_buffer to_shared_const_buffer () const - { - return shared_const_buffer (to_bytes ()); - } + std::shared_ptr> to_bytes () const; + nano::shared_const_buffer to_shared_const_buffer () const; + nano::message_header header; }; class work_pool; diff --git a/nano/node/confirmation_height_processor.cpp b/nano/node/confirmation_height_processor.cpp index 3a19fde2..9e83228c 100644 --- a/nano/node/confirmation_height_processor.cpp +++ b/nano/node/confirmation_height_processor.cpp @@ -1,10 +1,10 @@ #include #include #include +#include #include #include #include -#include #include #include #include diff --git a/nano/node/distributed_work.cpp b/nano/node/distributed_work.cpp index 60518b02..90d1dda4 100644 --- a/nano/node/distributed_work.cpp +++ b/nano/node/distributed_work.cpp @@ -63,7 +63,7 @@ void nano::distributed_work::start () need_resolve.pop_back (); auto this_l (shared_from_this ()); boost::system::error_code ec; - auto parsed_address (boost::asio::ip::address_v6::from_string (current.first, ec)); + auto parsed_address (boost::asio::ip::make_address_v6 (current.first, ec)); if (!ec) { outstanding[parsed_address] = current.second; @@ -394,115 +394,3 @@ void nano::distributed_work::add_bad_peer (boost::asio::ip::address const & addr nano::lock_guard guard (mutex); bad_peers.emplace_back (boost::str (boost::format ("%1%:%2%") % address_a % port_a)); } - -nano::distributed_work_factory::distributed_work_factory (nano::node & node_a) : -node (node_a) -{ -} - -nano::distributed_work_factory::~distributed_work_factory () -{ - stop (); -} - -bool nano::distributed_work_factory::make (nano::root const & root_a, std::vector> const & peers_a, std::function)> const & callback_a, uint64_t difficulty_a, boost::optional const & account_a) -{ - return make (1, root_a, peers_a, callback_a, difficulty_a, account_a); -} - -bool nano::distributed_work_factory::make (unsigned int backoff_a, nano::root const & root_a, std::vector> const & peers_a, std::function)> const & callback_a, uint64_t difficulty_a, boost::optional const & account_a) -{ - bool error_l{ true }; - if (!stopped) - { - cleanup_finished (); - if (node.work_generation_enabled ()) - { - auto distributed (std::make_shared (node, root_a, peers_a, backoff_a, callback_a, difficulty_a, account_a)); - { - nano::lock_guard guard (mutex); - items[root_a].emplace_back (distributed); - } - distributed->start (); - error_l = false; - } - } - return error_l; -} - -void nano::distributed_work_factory::cancel (nano::root const & root_a, bool const local_stop) -{ - nano::lock_guard guard_l (mutex); - auto existing_l (items.find (root_a)); - if (existing_l != items.end ()) - { - for (auto & distributed_w : existing_l->second) - { - if (auto distributed_l = distributed_w.lock ()) - { - // Send work_cancel to work peers and stop local work generation - distributed_l->cancel_once (); - } - } - items.erase (existing_l); - } -} - -void nano::distributed_work_factory::cleanup_finished () -{ - nano::lock_guard guard (mutex); - for (auto it (items.begin ()), end (items.end ()); it != end;) - { - it->second.erase (std::remove_if (it->second.begin (), it->second.end (), [](auto distributed_a) { - return distributed_a.expired (); - }), - it->second.end ()); - - if (it->second.empty ()) - { - it = items.erase (it); - } - else - { - ++it; - } - } -} - -void nano::distributed_work_factory::stop () -{ - if (!stopped.exchange (true)) - { - // Cancel any ongoing work - std::unordered_set roots_l; - nano::unique_lock lock_l (mutex); - for (auto const & item_l : items) - { - roots_l.insert (item_l.first); - } - lock_l.unlock (); - for (auto const & root_l : roots_l) - { - cancel (root_l, true); - } - lock_l.lock (); - items.clear (); - } -} - -namespace nano -{ -std::unique_ptr collect_seq_con_info (distributed_work_factory & distributed_work, const std::string & name) -{ - size_t item_count = 0; - { - nano::lock_guard guard (distributed_work.mutex); - item_count = distributed_work.items.size (); - } - - auto composite = std::make_unique (name); - auto sizeof_item_element = sizeof (decltype (distributed_work.items)::value_type); - composite->add_component (std::make_unique (seq_con_info{ "items", item_count, sizeof_item_element })); - return composite; -} -} \ No newline at end of file diff --git a/nano/node/distributed_work.hpp b/nano/node/distributed_work.hpp index f05843af..623bcb5b 100644 --- a/nano/node/distributed_work.hpp +++ b/nano/node/distributed_work.hpp @@ -1,16 +1,26 @@ #pragma once -#include -#include +#include +#include +#include #include #include #include +#include #include using request_type = boost::beast::http::request; +namespace boost +{ +namespace asio +{ + class io_context; +} +} + namespace nano { class node; @@ -81,24 +91,4 @@ public: std::vector bad_peers; // websocket std::string winner; // websocket }; - -class distributed_work_factory final -{ -public: - distributed_work_factory (nano::node &); - ~distributed_work_factory (); - bool make (nano::root const &, std::vector> const &, std::function)> const &, uint64_t, boost::optional const & = boost::none); - bool make (unsigned int, nano::root const &, std::vector> const &, std::function)> const &, uint64_t, boost::optional const & = boost::none); - void cancel (nano::root const &, bool const local_stop = false); - void cleanup_finished (); - void stop (); - - nano::node & node; - std::unordered_map>> items; - std::mutex mutex; - std::atomic stopped{ false }; -}; - -class seq_con_info_component; -std::unique_ptr collect_seq_con_info (distributed_work_factory & distributed_work, const std::string & name); } \ No newline at end of file diff --git a/nano/node/distributed_work_factory.cpp b/nano/node/distributed_work_factory.cpp new file mode 100644 index 00000000..cc8838e2 --- /dev/null +++ b/nano/node/distributed_work_factory.cpp @@ -0,0 +1,115 @@ +#include +#include +#include + +nano::distributed_work_factory::distributed_work_factory (nano::node & node_a) : +node (node_a) +{ +} + +nano::distributed_work_factory::~distributed_work_factory () +{ + stop (); +} + +bool nano::distributed_work_factory::make (nano::root const & root_a, std::vector> const & peers_a, std::function)> const & callback_a, uint64_t difficulty_a, boost::optional const & account_a) +{ + return make (1, root_a, peers_a, callback_a, difficulty_a, account_a); +} + +bool nano::distributed_work_factory::make (unsigned int backoff_a, nano::root const & root_a, std::vector> const & peers_a, std::function)> const & callback_a, uint64_t difficulty_a, boost::optional const & account_a) +{ + bool error_l{ true }; + if (!stopped) + { + cleanup_finished (); + if (node.work_generation_enabled ()) + { + auto distributed (std::make_shared (node, root_a, peers_a, backoff_a, callback_a, difficulty_a, account_a)); + { + nano::lock_guard guard (mutex); + items[root_a].emplace_back (distributed); + } + distributed->start (); + error_l = false; + } + } + return error_l; +} + +void nano::distributed_work_factory::cancel (nano::root const & root_a, bool const local_stop) +{ + nano::lock_guard guard_l (mutex); + auto existing_l (items.find (root_a)); + if (existing_l != items.end ()) + { + for (auto & distributed_w : existing_l->second) + { + if (auto distributed_l = distributed_w.lock ()) + { + // Send work_cancel to work peers and stop local work generation + distributed_l->cancel_once (); + } + } + items.erase (existing_l); + } +} + +void nano::distributed_work_factory::cleanup_finished () +{ + nano::lock_guard guard (mutex); + for (auto it (items.begin ()), end (items.end ()); it != end;) + { + it->second.erase (std::remove_if (it->second.begin (), it->second.end (), [](auto distributed_a) { + return distributed_a.expired (); + }), + it->second.end ()); + + if (it->second.empty ()) + { + it = items.erase (it); + } + else + { + ++it; + } + } +} + +void nano::distributed_work_factory::stop () +{ + if (!stopped.exchange (true)) + { + // Cancel any ongoing work + std::unordered_set roots_l; + nano::unique_lock lock_l (mutex); + for (auto const & item_l : items) + { + roots_l.insert (item_l.first); + } + lock_l.unlock (); + for (auto const & root_l : roots_l) + { + cancel (root_l, true); + } + lock_l.lock (); + items.clear (); + } +} + +namespace nano +{ +std::unique_ptr collect_seq_con_info (distributed_work_factory & distributed_work, const std::string & name) +{ + size_t item_count = 0; + { + nano::lock_guard guard (distributed_work.mutex); + item_count = distributed_work.items.size (); + } + + auto composite = std::make_unique (name); + auto sizeof_item_element = sizeof (decltype (distributed_work.items)::value_type); + composite->add_component (std::make_unique (seq_con_info{ "items", item_count, sizeof_item_element })); + return composite; +} +} \ No newline at end of file diff --git a/nano/node/distributed_work_factory.hpp b/nano/node/distributed_work_factory.hpp new file mode 100644 index 00000000..bb730718 --- /dev/null +++ b/nano/node/distributed_work_factory.hpp @@ -0,0 +1,38 @@ +#pragma once + +#include + +#include + +#include +#include +#include +#include +#include + +namespace nano +{ +class node; +class distributed_work; +class root; + +class distributed_work_factory final +{ +public: + distributed_work_factory (nano::node &); + ~distributed_work_factory (); + bool make (nano::root const &, std::vector> const &, std::function)> const &, uint64_t, boost::optional const & = boost::none); + bool make (unsigned int, nano::root const &, std::vector> const &, std::function)> const &, uint64_t, boost::optional const & = boost::none); + void cancel (nano::root const &, bool const local_stop = false); + void cleanup_finished (); + void stop (); + + nano::node & node; + std::unordered_map>> items; + std::mutex mutex; + std::atomic stopped{ false }; +}; + +class seq_con_info_component; +std::unique_ptr collect_seq_con_info (distributed_work_factory & distributed_work, const std::string & name); +} \ No newline at end of file diff --git a/nano/node/election.cpp b/nano/node/election.cpp index c4c519b9..1b269544 100644 --- a/nano/node/election.cpp +++ b/nano/node/election.cpp @@ -1,6 +1,8 @@ #include #include +#include + nano::election_vote_result::election_vote_result (bool replay_a, bool processed_a) { replay = replay_a; diff --git a/nano/node/gap_cache.cpp b/nano/node/gap_cache.cpp index ef06d318..55352bf3 100644 --- a/nano/node/gap_cache.cpp +++ b/nano/node/gap_cache.cpp @@ -2,6 +2,8 @@ #include #include +#include + nano::gap_cache::gap_cache (nano::node & node_a) : node (node_a) { diff --git a/nano/node/gap_cache.hpp b/nano/node/gap_cache.hpp index 5a123e2d..b5d068e4 100644 --- a/nano/node/gap_cache.hpp +++ b/nano/node/gap_cache.hpp @@ -7,7 +7,6 @@ #include #include #include -#include #include #include diff --git a/nano/node/ipc.cpp b/nano/node/ipc.cpp index b98b3dd7..ab47a486 100644 --- a/nano/node/ipc.cpp +++ b/nano/node/ipc.cpp @@ -1,26 +1,18 @@ +#include +#include #include #include +#include #include #include #include #include #include -#include -#include #include -#include #include -#include -#include -#include #include -#include -#include -#include -#include -#include using namespace boost::log; diff --git a/nano/node/ipc.hpp b/nano/node/ipc.hpp index abbeff27..98cf07a3 100644 --- a/nano/node/ipc.hpp +++ b/nano/node/ipc.hpp @@ -1,7 +1,6 @@ #pragma once #include -#include #include #include diff --git a/nano/node/json_handler.cpp b/nano/node/json_handler.cpp index a0a64693..118842c5 100644 --- a/nano/node/json_handler.cpp +++ b/nano/node/json_handler.cpp @@ -2,27 +2,17 @@ #include #include #include -#include +#include #include #include #include #include -#include -#include -#include -#include #include #include -#include #include #include -#include -#include -#include -#include -#include namespace { @@ -1390,9 +1380,9 @@ void nano::json_handler::block_create () rpc_l->response (ostream.str ()); }; // Wrapper from argument to lambda capture, to extend the block's scope - auto get_callback_l = [rpc_l, this, block_response_put_l](std::shared_ptr block_a) { + auto get_callback_l = [rpc_l, block_response_put_l](std::shared_ptr block_a) { // Callback upon work generation success or failure - return [block_a, rpc_l, this, block_response_put_l](boost::optional const & work_a) { + return [block_a, rpc_l, block_response_put_l](boost::optional const & work_a) { if (block_a != nullptr) { if (work_a.is_initialized ()) @@ -1600,7 +1590,7 @@ void nano::json_handler::bootstrap () std::string port_text = request.get ("port"); const bool bypass_frontier_confirmation = request.get ("bypass_frontier_confirmation", false); boost::system::error_code address_ec; - auto address (boost::asio::ip::address_v6::from_string (address_text, address_ec)); + auto address (boost::asio::ip::make_address_v6 (address_text, address_ec)); if (!address_ec) { uint16_t port; diff --git a/nano/node/json_payment_observer.hpp b/nano/node/json_payment_observer.hpp index 257de782..cd755ea0 100644 --- a/nano/node/json_payment_observer.hpp +++ b/nano/node/json_payment_observer.hpp @@ -1,10 +1,8 @@ #pragma once #include -#include #include -#include namespace nano { diff --git a/nano/node/lmdb/lmdb.cpp b/nano/node/lmdb/lmdb.cpp index 0288b9f2..2d707679 100644 --- a/nano/node/lmdb/lmdb.cpp +++ b/nano/node/lmdb/lmdb.cpp @@ -4,9 +4,11 @@ #include #include #include +#include #include -#include +#include +#include #include #include @@ -1077,3 +1079,6 @@ bool nano::mdb_store::upgrade_counters::are_equal () const { return (before_v0 == after_v0) && (before_v1 == after_v1); } + +// Explicitly instantiate +template class nano::block_store_partial; \ No newline at end of file diff --git a/nano/node/lmdb/lmdb.hpp b/nano/node/lmdb/lmdb.hpp index d1f1cfc4..bba263ce 100644 --- a/nano/node/lmdb/lmdb.hpp +++ b/nano/node/lmdb/lmdb.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include #include @@ -11,13 +10,18 @@ #include #include -#include #include -#include - #include +namespace boost +{ +namespace filesystem +{ + class path; +} +} + namespace nano { using mdb_val = db_val; @@ -275,4 +279,6 @@ template <> mdb_val::db_val (size_t size_a, void * data_a); template <> void mdb_val::convert_buffer_to_value (); + +extern template class block_store_partial; } diff --git a/nano/node/lmdb/lmdb_env.cpp b/nano/node/lmdb/lmdb_env.cpp index cf307125..61bc9f37 100644 --- a/nano/node/lmdb/lmdb_env.cpp +++ b/nano/node/lmdb/lmdb_env.cpp @@ -1,5 +1,7 @@ #include +#include + nano::mdb_env::mdb_env (bool & error_a, boost::filesystem::path const & path_a, int max_dbs_a, bool use_no_mem_init_a, size_t map_size_a) { init (error_a, path_a, max_dbs_a, use_no_mem_init_a, map_size_a); diff --git a/nano/node/lmdb/lmdb_txn.cpp b/nano/node/lmdb/lmdb_txn.cpp index 1b0a705a..f32ed460 100644 --- a/nano/node/lmdb/lmdb_txn.cpp +++ b/nano/node/lmdb/lmdb_txn.cpp @@ -1,11 +1,12 @@ #include #include +#include #include #include #include #include -#include +#include // Some builds (mac) fail due to "Boost.Stacktrace requires `_Unwind_Backtrace` function". #ifndef _WIN32 diff --git a/nano/node/lmdb/lmdb_txn.hpp b/nano/node/lmdb/lmdb_txn.hpp index a6ca82c1..a5ce109e 100644 --- a/nano/node/lmdb/lmdb_txn.hpp +++ b/nano/node/lmdb/lmdb_txn.hpp @@ -4,7 +4,7 @@ #include #include -#include +#include #include #include diff --git a/nano/node/logging.cpp b/nano/node/logging.cpp index b296203d..fb28b99a 100644 --- a/nano/node/logging.cpp +++ b/nano/node/logging.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include @@ -8,7 +9,6 @@ #include #include #include -#include #ifdef BOOST_WINDOWS #include diff --git a/nano/node/logging.hpp b/nano/node/logging.hpp index 1661aa98..2da20c4f 100644 --- a/nano/node/logging.hpp +++ b/nano/node/logging.hpp @@ -1,21 +1,39 @@ #pragma once #include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include #include #define FATAL_LOG_PREFIX "FATAL ERROR: " +namespace boost +{ +BOOST_LOG_OPEN_NAMESPACE +namespace sinks +{ + class text_file_backend; + + template + class synchronous_sink; +} + +BOOST_LOG_CLOSE_NAMESPACE + +namespace filesystem +{ + class path; +} +} + namespace nano { class tomlconfig; +class jsonconfig; class logging final { public: diff --git a/nano/node/network.cpp b/nano/node/network.cpp index 4f4f61ed..fb1720ae 100644 --- a/nano/node/network.cpp +++ b/nano/node/network.cpp @@ -1,8 +1,13 @@ +#include +#include #include #include +#include + +#include +#include #include -#include nano::network::network (nano::node & node_a, uint16_t port_a) : buffer_container (node_a.stats, nano::network::buffer_size, 4096), // 2Mb receive buffer @@ -95,9 +100,9 @@ void nano::network::send_keepalive (std::shared_ptr ch void nano::network::send_keepalive_self (std::shared_ptr channel_a) { nano::keepalive message; - if (node.config.external_address != boost::asio::ip::address_v6{} && node.config.external_port != 0) + if (node.config.external_address != boost::asio::ip::address_v6{}.to_string () && node.config.external_port != 0) { - message.peers[0] = nano::endpoint (node.config.external_address, node.config.external_port); + message.peers[0] = nano::endpoint (boost::asio::ip::make_address_v6 (node.config.external_address), node.config.external_port); } else { @@ -106,7 +111,7 @@ void nano::network::send_keepalive_self (std::shared_ptr block_a) * if the votes for a block have not arrived in time. */ const size_t max_endpoints = 32; - random_pool::shuffle (list->begin (), list->end ()); + nano::random_pool_shuffle (list->begin (), list->end ()); if (list->size () > max_endpoints) { list->erase (list->begin () + max_endpoints, list->end ()); @@ -651,7 +656,7 @@ std::deque> nano::network::list (size_ std::deque> result; tcp_channels.list (result); udp_channels.list (result); - random_pool::shuffle (result.begin (), result.end ()); + nano::random_pool_shuffle (result.begin (), result.end ()); if (result.size () > count_a) { result.resize (count_a, nullptr); diff --git a/nano/node/network.hpp b/nano/node/network.hpp index da2850a1..c9d61335 100644 --- a/nano/node/network.hpp +++ b/nano/node/network.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include #include @@ -9,6 +8,7 @@ #include #include +#include namespace nano { diff --git a/nano/node/node.cpp b/nano/node/node.cpp index 65c5879c..762e9d8f 100644 --- a/nano/node/node.cpp +++ b/nano/node/node.cpp @@ -1,21 +1,21 @@ -#include -#include +#include #include #include #include +#include #include +#include #if NANO_ROCKSDB #include #endif -#include +#include #include #include #include #include -#include #include double constexpr nano::node::price_max; @@ -135,7 +135,7 @@ bootstrap_initiator (*this), bootstrap (config.peering_port, *this), application_path (application_path_a), port_mapping (*this), -vote_processor (*this), +vote_processor (checker, active, store, observers, stats, config, logger, online_reps, ledger, network_params), rep_crawler (*this), warmed_up (0), block_processor (*this, write_database_queue), @@ -143,7 +143,7 @@ block_processor_thread ([this]() { nano::thread_role::set (nano::thread_role::name::block_processing); this->block_processor.process_blocks (); }), -online_reps (*this, config.online_weight_minimum.number ()), +online_reps (ledger, network_params, config.online_weight_minimum.number ()), vote_uniquer (block_uniquer), active (*this), confirmation_height_processor (pending_confirmation_height, ledger, active, write_database_queue, config.conf_height_processor_batch_min_time, logger), @@ -155,8 +155,8 @@ startup_time (std::chrono::steady_clock::now ()) { if (config.websocket_config.enabled) { - auto endpoint_l (nano::tcp_endpoint (config.websocket_config.address, config.websocket_config.port)); - websocket_server = std::make_shared (*this, endpoint_l); + auto endpoint_l (nano::tcp_endpoint (boost::asio::ip::make_address_v6 (config.websocket_config.address), config.websocket_config.port)); + websocket_server = std::make_shared (logger, wallets, io_ctx, endpoint_l); this->websocket_server->run (); } @@ -684,7 +684,7 @@ void nano::node::start () this_l->bootstrap_wallet (); }); } - if (config.external_address == boost::asio::ip::address_v6{}.any ()) + if (config.external_address == boost::asio::ip::address_v6{}.any ().to_string ()) { port_mapping.start (); } diff --git a/nano/node/node.hpp b/nano/node/node.hpp index 983394ab..a6bb9cf2 100644 --- a/nano/node/node.hpp +++ b/nano/node/node.hpp @@ -1,20 +1,15 @@ #pragma once -#include #include -#include #include #include +#include #include #include #include -#include -#include -#include #include #include -#include -#include +#include #include #include #include @@ -27,27 +22,28 @@ #include #include #include -#include #include #include +#include -#include #include #include #include -#include #include #include -#include #include -#include #include -#include +#include #include namespace nano { +namespace websocket +{ + class listener; +} + class node; class work_pool; @@ -173,7 +169,7 @@ public: nano::rep_crawler rep_crawler; unsigned warmed_up; nano::block_processor block_processor; - boost::thread block_processor_thread; + std::thread block_processor_thread; nano::block_arrival block_arrival; nano::online_reps online_reps; nano::votes_cache votes_cache; diff --git a/nano/node/node_observers.hpp b/nano/node/node_observers.hpp index 5666d8cb..b9ee1b08 100644 --- a/nano/node/node_observers.hpp +++ b/nano/node/node_observers.hpp @@ -1,11 +1,9 @@ #pragma once -#include #include #include #include #include -#include namespace nano { diff --git a/nano/node/node_pow_server_config.cpp b/nano/node/node_pow_server_config.cpp index b98e3aa9..b4f9d93d 100644 --- a/nano/node/node_pow_server_config.cpp +++ b/nano/node/node_pow_server_config.cpp @@ -1,5 +1,3 @@ -#include -#include #include #include diff --git a/nano/node/node_rpc_config.cpp b/nano/node/node_rpc_config.cpp index 75e7cbb5..cadea39b 100644 --- a/nano/node/node_rpc_config.cpp +++ b/nano/node/node_rpc_config.cpp @@ -1,7 +1,5 @@ -#include #include #include -#include #include #include diff --git a/nano/node/node_rpc_config.hpp b/nano/node/node_rpc_config.hpp index f175e1f0..f2f24961 100644 --- a/nano/node/node_rpc_config.hpp +++ b/nano/node/node_rpc_config.hpp @@ -2,10 +2,16 @@ #include -#include - #include +namespace boost +{ +namespace filesystem +{ + class path; +} +} + namespace nano { class tomlconfig; diff --git a/nano/node/nodeconfig.cpp b/nano/node/nodeconfig.cpp index cce5a840..43fd4bc8 100644 --- a/nano/node/nodeconfig.cpp +++ b/nano/node/nodeconfig.cpp @@ -5,9 +5,11 @@ #include #include #include -// NOTE: to reduce compile times, this include can be replaced by more narrow includes -// once nano::network is factored out of node.{c|h}pp -#include +#include + +#include + +#include namespace { @@ -25,7 +27,8 @@ node_config (0, nano::logging ()) nano::node_config::node_config (uint16_t peering_port_a, nano::logging const & logging_a) : peering_port (peering_port_a), -logging (logging_a) +logging (logging_a), +external_address (boost::asio::ip::address_v6{}.to_string ()) { // The default constructor passes 0 to indicate we should use the default port, // which is determined at node startup based on active network. @@ -86,7 +89,7 @@ nano::error nano::node_config::serialize_toml (nano::tomlconfig & toml) const toml.put ("unchecked_cutoff_time", unchecked_cutoff_time.count (), "Number of seconds before deleting an unchecked entry.\nWarning: lower values (e.g., 3600 seconds, or 1 hour) may result in unsuccessful bootstraps, especially a bootstrap from scratch.\ntype:seconds"); toml.put ("tcp_io_timeout", tcp_io_timeout.count (), "Timeout for TCP connect-, read- and write operations.\nWarning: a low value (e.g., below 5 seconds) may result in TCP connections failing.\ntype:seconds"); toml.put ("pow_sleep_interval", pow_sleep_interval.count (), "Time to sleep between batch work generation attempts. Reduces max CPU usage at the expense of a longer generation time.\ntype:nanoseconds"); - toml.put ("external_address", external_address.to_string (), "The external address of this node (NAT). If not set, the node will request this information via UPnP.\ntype:string,ip"); + toml.put ("external_address", external_address, "The external address of this node (NAT). If not set, the node will request this information via UPnP.\ntype:string,ip"); toml.put ("external_port", external_port, "The external port number of this node (NAT). Only used if external_address is set.\ntype:uint16"); toml.put ("tcp_incoming_connections_max", tcp_incoming_connections_max, "Maximum number of incoming TCP connections.\ntype:uint64"); toml.put ("use_memory_pools", use_memory_pools, "If true, allocate memory from memory pools. Enabling this may improve performance. Memory is never released to the OS.\ntype:bool"); @@ -302,7 +305,10 @@ nano::error nano::node_config::deserialize_toml (nano::tomlconfig & toml) toml.get ("enable_voting", enable_voting); toml.get ("allow_local_peers", allow_local_peers); toml.get (signature_checker_threads_key, signature_checker_threads); - toml.get ("external_address", external_address); + + boost::asio::ip::address_v6 external_address_l; + toml.get ("external_address", external_address_l); + external_address = external_address_l.to_string (); toml.get ("external_port", external_port); toml.get ("tcp_incoming_connections_max", tcp_incoming_connections_max); @@ -444,7 +450,7 @@ nano::error nano::node_config::serialize_json (nano::jsonconfig & json) const json.put ("unchecked_cutoff_time", unchecked_cutoff_time.count ()); json.put ("tcp_io_timeout", tcp_io_timeout.count ()); json.put ("pow_sleep_interval", pow_sleep_interval.count ()); - json.put ("external_address", external_address.to_string ()); + json.put ("external_address", external_address); json.put ("external_port", external_port); json.put ("tcp_incoming_connections_max", tcp_incoming_connections_max); json.put ("use_memory_pools", use_memory_pools); @@ -574,7 +580,7 @@ bool nano::node_config::upgrade_json (unsigned version_a, nano::jsonconfig & jso json.put_child ("diagnostics", diagnostics_l); json.put ("tcp_io_timeout", tcp_io_timeout.count ()); json.put (pow_sleep_interval_key, pow_sleep_interval.count ()); - json.put ("external_address", external_address.to_string ()); + json.put ("external_address", external_address); json.put ("external_port", external_port); json.put ("tcp_incoming_connections_max", tcp_incoming_connections_max); json.put ("vote_generator_delay", vote_generator_delay.count ()); @@ -733,7 +739,9 @@ nano::error nano::node_config::deserialize_json (bool & upgraded_a, nano::jsonco json.get ("enable_voting", enable_voting); json.get ("allow_local_peers", allow_local_peers); json.get (signature_checker_threads_key, signature_checker_threads); - json.get ("external_address", external_address); + boost::asio::ip::address_v6 external_address_l; + json.get ("external_address", external_address_l); + external_address = external_address_l.to_string (); json.get ("external_port", external_port); json.get ("tcp_incoming_connections_max", tcp_incoming_connections_max); diff --git a/nano/node/nodeconfig.hpp b/nano/node/nodeconfig.hpp index 139ae2b5..e24a0e37 100644 --- a/nano/node/nodeconfig.hpp +++ b/nano/node/nodeconfig.hpp @@ -56,10 +56,10 @@ public: nano::amount online_weight_minimum{ 60000 * nano::Gxrb_ratio }; unsigned online_weight_quorum{ 50 }; unsigned password_fanout{ 1024 }; - unsigned io_threads{ std::max (4, boost::thread::hardware_concurrency ()) }; - unsigned network_threads{ std::max (4, boost::thread::hardware_concurrency ()) }; - unsigned work_threads{ std::max (4, boost::thread::hardware_concurrency ()) }; - unsigned signature_checker_threads{ (boost::thread::hardware_concurrency () != 0) ? boost::thread::hardware_concurrency () - 1 : 0 }; /* The calling thread does checks as well so remove it from the number of threads used */ + unsigned io_threads{ std::max (4, std::thread::hardware_concurrency ()) }; + unsigned network_threads{ std::max (4, std::thread::hardware_concurrency ()) }; + unsigned work_threads{ std::max (4, std::thread::hardware_concurrency ()) }; + unsigned signature_checker_threads{ (std::thread::hardware_concurrency () != 0) ? std::thread::hardware_concurrency () - 1 : 0 }; /* The calling thread does checks as well so remove it from the number of threads used */ bool enable_voting{ false }; unsigned bootstrap_connections{ 4 }; unsigned bootstrap_connections_max{ 64 }; @@ -73,7 +73,7 @@ public: bool allow_local_peers{ !network_params.network.is_live_network () }; // disable by default for live network nano::stat_config stat_config; nano::ipc::ipc_config ipc_config; - boost::asio::ip::address_v6 external_address{ boost::asio::ip::address_v6{} }; + std::string external_address; uint16_t external_port{ 0 }; std::chrono::milliseconds block_processor_batch_max_time{ std::chrono::milliseconds (5000) }; std::chrono::seconds unchecked_cutoff_time{ std::chrono::seconds (4 * 60 * 60) }; // 4 hours diff --git a/nano/node/online_reps.cpp b/nano/node/online_reps.cpp index cc03cdea..2367976d 100644 --- a/nano/node/online_reps.cpp +++ b/nano/node/online_reps.cpp @@ -1,22 +1,25 @@ -#include #include +#include +#include +#include #include -nano::online_reps::online_reps (nano::node & node_a, nano::uint128_t minimum_a) : -node (node_a), +nano::online_reps::online_reps (nano::ledger & ledger_a, nano::network_params & network_params_a, nano::uint128_t minimum_a) : +ledger (ledger_a), +network_params (network_params_a), minimum (minimum_a) { - if (!node.ledger.store.init_error ()) + if (!ledger.store.init_error ()) { - auto transaction (node.ledger.store.tx_begin_read ()); + auto transaction (ledger.store.tx_begin_read ()); online = trend (transaction); } } void nano::online_reps::observe (nano::account const & rep_a) { - if (node.ledger.weight (rep_a) > 0) + if (ledger.weight (rep_a) > 0) { nano::lock_guard lock (mutex); reps.insert (rep_a); @@ -25,13 +28,13 @@ void nano::online_reps::observe (nano::account const & rep_a) void nano::online_reps::sample () { - auto transaction (node.ledger.store.tx_begin_write ()); + auto transaction (ledger.store.tx_begin_write ()); // Discard oldest entries - while (node.ledger.store.online_weight_count (transaction) >= node.network_params.node.max_weight_samples) + while (ledger.store.online_weight_count (transaction) >= network_params.node.max_weight_samples) { - auto oldest (node.ledger.store.online_weight_begin (transaction)); - assert (oldest != node.ledger.store.online_weight_end ()); - node.ledger.store.online_weight_del (transaction, oldest->first); + auto oldest (ledger.store.online_weight_begin (transaction)); + assert (oldest != ledger.store.online_weight_end ()); + ledger.store.online_weight_del (transaction, oldest->first); } // Calculate current active rep weight nano::uint128_t current; @@ -42,9 +45,9 @@ void nano::online_reps::sample () } for (auto & i : reps_copy) { - current += node.ledger.weight (i); + current += ledger.weight (i); } - node.ledger.store.online_weight_put (transaction, std::chrono::system_clock::now ().time_since_epoch ().count (), current); + ledger.store.online_weight_put (transaction, std::chrono::system_clock::now ().time_since_epoch ().count (), current); auto trend_l (trend (transaction)); nano::lock_guard lock (mutex); online = trend_l; @@ -53,9 +56,9 @@ void nano::online_reps::sample () nano::uint128_t nano::online_reps::trend (nano::transaction & transaction_a) { std::vector items; - items.reserve (node.network_params.node.max_weight_samples + 1); + items.reserve (network_params.node.max_weight_samples + 1); items.push_back (minimum); - for (auto i (node.ledger.store.online_weight_begin (transaction_a)), n (node.ledger.store.online_weight_end ()); i != n; ++i) + for (auto i (ledger.store.online_weight_begin (transaction_a)), n (ledger.store.online_weight_end ()); i != n; ++i) { items.push_back (i->second.number ()); } diff --git a/nano/node/online_reps.hpp b/nano/node/online_reps.hpp index 27488bbe..64789717 100644 --- a/nano/node/online_reps.hpp +++ b/nano/node/online_reps.hpp @@ -9,15 +9,15 @@ namespace nano { -class node; +class ledger; +class network_params; class transaction; /** Track online representatives and trend online weight */ class online_reps final { public: - online_reps (nano::node &, nano::uint128_t); - + online_reps (nano::ledger & ledger_a, nano::network_params & network_params_a, nano::uint128_t minimum_a); /** Add voting account \p rep_account to the set of online representatives */ void observe (nano::account const & rep_account); /** Called periodically to sample online weight */ @@ -30,7 +30,8 @@ public: private: nano::uint128_t trend (nano::transaction &); mutable std::mutex mutex; - nano::node & node; + nano::ledger & ledger; + nano::network_params & network_params; std::unordered_set reps; nano::uint128_t online; nano::uint128_t minimum; diff --git a/nano/node/openclwork.cpp b/nano/node/openclwork.cpp index c06048b9..14a8f15a 100644 --- a/nano/node/openclwork.cpp +++ b/nano/node/openclwork.cpp @@ -1,13 +1,13 @@ #include -#include -#include +#include #include #include #include +#include + #include #include -#include #include #include diff --git a/nano/node/openclwork.hpp b/nano/node/openclwork.hpp index 5b8b93d6..1ca55b46 100644 --- a/nano/node/openclwork.hpp +++ b/nano/node/openclwork.hpp @@ -1,14 +1,11 @@ #pragma once -#include -#include #include #include #include -#include -#include +#include #include #include diff --git a/nano/node/portmapping.cpp b/nano/node/portmapping.cpp index a4d3ddac..1eb4e02f 100644 --- a/nano/node/portmapping.cpp +++ b/nano/node/portmapping.cpp @@ -1,6 +1,8 @@ #include #include +#include + #include #include diff --git a/nano/node/portmapping.hpp b/nano/node/portmapping.hpp index cd42788d..64d51a16 100644 --- a/nano/node/portmapping.hpp +++ b/nano/node/portmapping.hpp @@ -1,8 +1,5 @@ #pragma once -#include -#include - #include #include diff --git a/nano/node/repcrawler.hpp b/nano/node/repcrawler.hpp index b1fb9b3a..c43a57d0 100644 --- a/nano/node/repcrawler.hpp +++ b/nano/node/repcrawler.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include @@ -13,7 +12,6 @@ #include #include -#include #include namespace mi = boost::multi_index; diff --git a/nano/node/rocksdb/rocksdb.cpp b/nano/node/rocksdb/rocksdb.cpp index 4b49727a..bf22a26f 100644 --- a/nano/node/rocksdb/rocksdb.cpp +++ b/nano/node/rocksdb/rocksdb.cpp @@ -5,6 +5,7 @@ #include #include +#include #include #include @@ -605,4 +606,6 @@ bool nano::rocksdb_store::copy_db (boost::filesystem::path const & destination_p bool nano::rocksdb_store::init_error () const { return error; -} \ No newline at end of file +} +// Explicitly instantiate +template class nano::block_store_partial; diff --git a/nano/node/rocksdb/rocksdb.hpp b/nano/node/rocksdb/rocksdb.hpp index cbe2f5bc..88ccd4c3 100644 --- a/nano/node/rocksdb/rocksdb.hpp +++ b/nano/node/rocksdb/rocksdb.hpp @@ -19,6 +19,7 @@ namespace nano { class logging_mt; class rocksdb_config; + /** * rocksdb implementation of the block store */ @@ -102,4 +103,6 @@ private: rocksdb::BlockBasedTableOptions get_table_options () const; nano::rocksdb_config rocksdb_config; }; + +extern template class block_store_partial; } diff --git a/nano/node/signatures.cpp b/nano/node/signatures.cpp index 4adb7845..f2fd5980 100644 --- a/nano/node/signatures.cpp +++ b/nano/node/signatures.cpp @@ -1,4 +1,7 @@ +#include +#include #include +#include #include nano::signature_checker::signature_checker (unsigned num_threads) : diff --git a/nano/node/signatures.hpp b/nano/node/signatures.hpp index caaa783d..61a6bb7a 100644 --- a/nano/node/signatures.hpp +++ b/nano/node/signatures.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include diff --git a/nano/node/socket.cpp b/nano/node/socket.cpp index 62b0ec60..02369927 100644 --- a/nano/node/socket.cpp +++ b/nano/node/socket.cpp @@ -1,6 +1,11 @@ +#include +#include +#include #include #include +#include + #include nano::socket::socket (std::shared_ptr node_a, boost::optional io_timeout_a, nano::socket::concurrency concurrency_a) : diff --git a/nano/node/socket.hpp b/nano/node/socket.hpp index 9dd291ff..41e726b1 100644 --- a/nano/node/socket.hpp +++ b/nano/node/socket.hpp @@ -1,15 +1,14 @@ #pragma once -#include +#include +#include #include -#include #include #include #include #include -#include #include namespace nano diff --git a/nano/node/testing.cpp b/nano/node/testing.cpp index d541ee58..a9d3fc54 100644 --- a/nano/node/testing.cpp +++ b/nano/node/testing.cpp @@ -5,7 +5,6 @@ #include #include -#include #include diff --git a/nano/node/testing.hpp b/nano/node/testing.hpp index b6324c21..df7cbbd2 100644 --- a/nano/node/testing.hpp +++ b/nano/node/testing.hpp @@ -1,7 +1,6 @@ #pragma once #include -#include #include #include diff --git a/nano/node/transport/tcp.cpp b/nano/node/transport/tcp.cpp index 4951e227..e78d9d86 100644 --- a/nano/node/transport/tcp.cpp +++ b/nano/node/transport/tcp.cpp @@ -2,6 +2,8 @@ #include #include +#include + nano::transport::channel_tcp::channel_tcp (nano::node & node_a, std::weak_ptr socket_a) : channel (node_a), socket (socket_a) diff --git a/nano/node/transport/tcp.hpp b/nano/node/transport/tcp.hpp index f2077443..3b42ce9f 100644 --- a/nano/node/transport/tcp.hpp +++ b/nano/node/transport/tcp.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include @@ -11,6 +10,8 @@ #include #include +#include + namespace nano { class bootstrap_server; diff --git a/nano/node/transport/transport.cpp b/nano/node/transport/transport.cpp index 20ecc7d9..b9a222aa 100644 --- a/nano/node/transport/transport.cpp +++ b/nano/node/transport/transport.cpp @@ -2,6 +2,8 @@ #include #include +#include + #include namespace @@ -131,14 +133,14 @@ bool nano::transport::reserved_address (nano::endpoint const & endpoint_a, bool static auto const ipv4_multicast_max (mapped_from_v4_bytes (0xeffffffful)); static auto const rfc6890_min (mapped_from_v4_bytes (0xf0000000ul)); static auto const rfc6890_max (mapped_from_v4_bytes (0xfffffffful)); - static auto const rfc6666_min (boost::asio::ip::address_v6::from_string ("100::")); - static auto const rfc6666_max (boost::asio::ip::address_v6::from_string ("100::ffff:ffff:ffff:ffff")); - static auto const rfc3849_min (boost::asio::ip::address_v6::from_string ("2001:db8::")); - static auto const rfc3849_max (boost::asio::ip::address_v6::from_string ("2001:db8:ffff:ffff:ffff:ffff:ffff:ffff")); - static auto const rfc4193_min (boost::asio::ip::address_v6::from_string ("fc00::")); - static auto const rfc4193_max (boost::asio::ip::address_v6::from_string ("fd00:ffff:ffff:ffff:ffff:ffff:ffff:ffff")); - static auto const ipv6_multicast_min (boost::asio::ip::address_v6::from_string ("ff00::")); - static auto const ipv6_multicast_max (boost::asio::ip::address_v6::from_string ("ff00:ffff:ffff:ffff:ffff:ffff:ffff:ffff")); + static auto const rfc6666_min (boost::asio::ip::make_address_v6 ("100::")); + static auto const rfc6666_max (boost::asio::ip::make_address_v6 ("100::ffff:ffff:ffff:ffff")); + static auto const rfc3849_min (boost::asio::ip::make_address_v6 ("2001:db8::")); + static auto const rfc3849_max (boost::asio::ip::make_address_v6 ("2001:db8:ffff:ffff:ffff:ffff:ffff:ffff")); + static auto const rfc4193_min (boost::asio::ip::make_address_v6 ("fc00::")); + static auto const rfc4193_max (boost::asio::ip::make_address_v6 ("fd00:ffff:ffff:ffff:ffff:ffff:ffff:ffff")); + static auto const ipv6_multicast_min (boost::asio::ip::make_address_v6 ("ff00::")); + static auto const ipv6_multicast_max (boost::asio::ip::make_address_v6 ("ff00:ffff:ffff:ffff:ffff:ffff:ffff:ffff")); if (endpoint_a.port () == 0) { result = true; diff --git a/nano/node/transport/transport.hpp b/nano/node/transport/transport.hpp index 398b60a4..ae200aed 100644 --- a/nano/node/transport/transport.hpp +++ b/nano/node/transport/transport.hpp @@ -1,11 +1,10 @@ #pragma once +#include #include #include #include -#include - namespace nano { class bandwidth_limiter final diff --git a/nano/node/transport/udp.cpp b/nano/node/transport/udp.cpp index f6712bb8..c8045295 100644 --- a/nano/node/transport/udp.cpp +++ b/nano/node/transport/udp.cpp @@ -1,8 +1,12 @@ +#include +#include #include #include #include #include +#include + nano::transport::channel_udp::channel_udp (nano::transport::udp_channels & channels_a, nano::endpoint const & endpoint_a, uint8_t protocol_version_a) : channel (channels_a.node), endpoint (endpoint_a), diff --git a/nano/node/transport/udp.hpp b/nano/node/transport/udp.hpp index 1f528efa..d399a791 100644 --- a/nano/node/transport/udp.hpp +++ b/nano/node/transport/udp.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include @@ -12,6 +11,7 @@ #include #include +#include namespace nano { diff --git a/nano/node/vote_processor.cpp b/nano/node/vote_processor.cpp index 7b90d3e7..2c5ef458 100644 --- a/nano/node/vote_processor.cpp +++ b/nano/node/vote_processor.cpp @@ -1,12 +1,34 @@ +#include +#include +#include #include +#include #include +#include +#include +#include +#include #include +#include +#include +#include -nano::vote_processor::vote_processor (nano::node & node_a) : -node (node_a), +#include + +nano::vote_processor::vote_processor (nano::signature_checker & checker_a, nano::active_transactions & active_a, nano::block_store & store_a, nano::node_observers & observers_a, nano::stat & stats_a, nano::node_config & config_a, nano::logger_mt & logger_a, nano::online_reps & online_reps_a, nano::ledger & ledger_a, nano::network_params & network_params_a) : +checker (checker_a), +active (active_a), +store (store_a), +observers (observers_a), +stats (stats_a), +config (config_a), +logger (logger_a), +online_reps (online_reps_a), +ledger (ledger_a), +network_params (network_params_a), started (false), stopped (false), -active (false), +is_active (false), thread ([this]() { nano::thread_role::set (nano::thread_role::name::vote_processing); process_loop (); @@ -36,7 +58,7 @@ void nano::vote_processor::process_loop () votes_l.swap (votes); log_this_iteration = false; - if (node.config.logging.network_logging () && votes_l.size () > 50) + if (config.logging.network_logging () && votes_l.size () > 50) { /* * Only log the timing information for this iteration if @@ -45,12 +67,12 @@ void nano::vote_processor::process_loop () log_this_iteration = true; elapsed.restart (); } - active = true; + is_active = true; lock.unlock (); verify_votes (votes_l); { - nano::unique_lock active_single_lock (node.active.mutex); - auto transaction (node.store.tx_begin_read ()); + nano::unique_lock active_single_lock (active.mutex); + auto transaction (store.tx_begin_read ()); uint64_t count (1); for (auto & i : votes_l) { @@ -66,7 +88,7 @@ void nano::vote_processor::process_loop () } } lock.lock (); - active = false; + is_active = false; lock.unlock (); condition.notify_all (); @@ -74,7 +96,7 @@ void nano::vote_processor::process_loop () if (log_this_iteration && elapsed.stop () > std::chrono::milliseconds (100)) { - node.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.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 ()))); } } else @@ -93,7 +115,7 @@ void nano::vote_processor::vote (std::shared_ptr vote_a, std::shared /* Random early delection levels Always process votes for test network (process = true) Stop processing with max 144 * 1024 votes */ - if (!node.network_params.network.is_test_network ()) + if (!network_params.network.is_test_network ()) { // Level 0 (< 0.1%) if (votes.size () < 96 * 1024) @@ -131,7 +153,7 @@ void nano::vote_processor::vote (std::shared_ptr vote_a, std::shared } else { - node.stats.inc (nano::stat::type::vote, nano::stat::detail::vote_overflow); + stats.inc (nano::stat::type::vote, nano::stat::detail::vote_overflow); } } } @@ -158,7 +180,7 @@ void nano::vote_processor::verify_votes (std::dequesignature.bytes.data ()); } nano::signature_check_set check = { size, messages.data (), lengths.data (), pub_keys.data (), signatures.data (), verifications.data () }; - node.checker.verify (check); + checker.verify (check); std::remove_reference_t result; auto i (0); for (auto & vote : votes_a) @@ -176,20 +198,20 @@ void nano::vote_processor::verify_votes (std::deque vote_a, std::shared_ptr channel_a, bool validated) { - assert (!node.active.mutex.try_lock ()); + assert (!active.mutex.try_lock ()); auto result (nano::vote_code::invalid); if (validated || !vote_a->validate ()) { - auto max_vote (node.store.vote_max (transaction_a, vote_a)); + auto max_vote (store.vote_max (transaction_a, vote_a)); result = nano::vote_code::replay; - if (!node.active.vote (vote_a, true)) + if (!active.vote (vote_a, true)) { result = nano::vote_code::vote; } switch (result) { case nano::vote_code::vote: - node.observers.vote.notify (vote_a, channel_a); + observers.vote.notify (vote_a, channel_a); case nano::vote_code::replay: // This tries to assist rep nodes that have lost track of their highest sequence number by replaying our highest known vote back to them // Only do this if the sequence number is significantly different to account for network reordering @@ -210,20 +232,20 @@ nano::vote_code nano::vote_processor::vote_blocking (nano::transaction const & t { case nano::vote_code::invalid: status = "Invalid"; - node.stats.inc (nano::stat::type::vote, nano::stat::detail::vote_invalid); + stats.inc (nano::stat::type::vote, nano::stat::detail::vote_invalid); break; case nano::vote_code::replay: status = "Replay"; - node.stats.inc (nano::stat::type::vote, nano::stat::detail::vote_replay); + stats.inc (nano::stat::type::vote, nano::stat::detail::vote_replay); break; case nano::vote_code::vote: status = "Vote"; - node.stats.inc (nano::stat::type::vote, nano::stat::detail::vote_valid); + stats.inc (nano::stat::type::vote, nano::stat::detail::vote_valid); break; } - if (node.config.logging.vote_logging ()) + if (config.logging.vote_logging ()) { - node.logger.try_log (boost::str (boost::format ("Vote from: %1% sequence: %2% block(s): %3%status: %4%") % vote_a->account.to_account () % std::to_string (vote_a->sequence) % vote_a->hashes_string () % status)); + logger.try_log (boost::str (boost::format ("Vote from: %1% sequence: %2% block(s): %3%status: %4%") % vote_a->account.to_account () % std::to_string (vote_a->sequence) % vote_a->hashes_string () % status)); } return result; } @@ -244,7 +266,7 @@ void nano::vote_processor::stop () void nano::vote_processor::flush () { nano::unique_lock lock (mutex); - while (active || !votes.empty ()) + while (is_active || !votes.empty ()) { condition.wait (lock); } @@ -258,12 +280,12 @@ void nano::vote_processor::calculate_weights () representatives_1.clear (); representatives_2.clear (); representatives_3.clear (); - auto supply (node.online_reps.online_stake ()); - auto rep_amounts = node.ledger.rep_weights.get_rep_amounts (); + auto supply (online_reps.online_stake ()); + auto rep_amounts = ledger.rep_weights.get_rep_amounts (); for (auto const & rep_amount : rep_amounts) { nano::account const & representative (rep_amount.first); - auto weight (node.ledger.weight (representative)); + auto weight (ledger.weight (representative)); if (weight > supply / 1000) // 0.1% or above (level 1) { representatives_1.insert (representative); diff --git a/nano/node/vote_processor.hpp b/nano/node/vote_processor.hpp index 49eb53fb..457aabd3 100644 --- a/nano/node/vote_processor.hpp +++ b/nano/node/vote_processor.hpp @@ -4,16 +4,25 @@ #include #include -#include - #include #include #include +#include #include namespace nano { -class node; +class signature_checker; +class active_transactions; +class block_store; +class node_observers; +class stats; +class node_config; +class logger_mt; +class online_reps; +class ledger; +class network_params; + class transaction; namespace transport { @@ -23,18 +32,29 @@ namespace transport class vote_processor final { public: - explicit vote_processor (nano::node &); + explicit vote_processor (nano::signature_checker & checker_a, nano::active_transactions & active_a, nano::block_store & store_a, nano::node_observers & observers_a, nano::stat & stats_a, nano::node_config & config_a, nano::logger_mt & logger_a, nano::online_reps & online_reps_a, nano::ledger & ledger_a, nano::network_params & network_params_a); void vote (std::shared_ptr, std::shared_ptr); /** Note: node.active.mutex lock is required */ nano::vote_code vote_blocking (nano::transaction const &, std::shared_ptr, std::shared_ptr, bool = false); void verify_votes (std::deque, std::shared_ptr>> &); void flush (); void calculate_weights (); - nano::node & node; void stop (); private: void process_loop (); + + nano::signature_checker & checker; + nano::active_transactions & active; + nano::block_store & store; + nano::node_observers & observers; + nano::stat & stats; + nano::node_config & config; + nano::logger_mt & logger; + nano::online_reps & online_reps; + nano::ledger & ledger; + nano::network_params & network_params; + std::deque, std::shared_ptr>> votes; /** Representatives levels for random early detection */ std::unordered_set representatives_1; @@ -44,8 +64,8 @@ private: std::mutex mutex; bool started; bool stopped; - bool active; - boost::thread thread; + bool is_active; + std::thread thread; friend std::unique_ptr collect_seq_con_info (vote_processor & vote_processor, const std::string & name); }; diff --git a/nano/node/voting.cpp b/nano/node/voting.cpp index f892db96..8465f49d 100644 --- a/nano/node/voting.cpp +++ b/nano/node/voting.cpp @@ -1,10 +1,24 @@ -#include +#include "transport/udp.hpp" + +#include +#include +#include +#include #include +#include +#include + +#include #include -nano::vote_generator::vote_generator (nano::node & node_a) : -node (node_a), +nano::vote_generator::vote_generator (nano::node_config & config_a, nano::block_store & store_a, nano::wallets & wallets_a, nano::vote_processor & vote_processor_a, nano::votes_cache & votes_cache_a, nano::network & network_a) : +config (config_a), +store (store_a), +wallets (wallets_a), +vote_processor (vote_processor_a), +votes_cache (votes_cache_a), +network (network_a), thread ([this]() { run (); }) { nano::unique_lock lock (mutex); @@ -47,11 +61,11 @@ void nano::vote_generator::send (nano::unique_lock & lock_a) } lock_a.unlock (); { - auto transaction (node.store.tx_begin_read ()); - node.wallets.foreach_representative ([this, &hashes_l, &transaction](nano::public_key const & pub_a, nano::raw_key const & prv_a) { - auto vote (this->node.store.vote_generate (transaction, pub_a, prv_a, hashes_l)); - this->node.vote_processor.vote (vote, std::make_shared (this->node.network.udp_channels, this->node.network.endpoint (), this->node.network_params.protocol.protocol_version)); - this->node.votes_cache.add (vote); + auto transaction (store.tx_begin_read ()); + wallets.foreach_representative ([this, &hashes_l, &transaction](nano::public_key const & pub_a, nano::raw_key const & prv_a) { + auto vote (this->store.vote_generate (transaction, pub_a, prv_a, hashes_l)); + this->vote_processor.vote (vote, std::make_shared (this->network.udp_channels, this->network.endpoint (), this->network_params.protocol.protocol_version)); + this->votes_cache.add (vote); }); } lock_a.lock (); @@ -73,10 +87,10 @@ void nano::vote_generator::run () } else { - condition.wait_for (lock, node.config.vote_generator_delay, [this]() { return this->hashes.size () >= 12; }); - if (hashes.size () >= node.config.vote_generator_threshold && hashes.size () < 12) + condition.wait_for (lock, config.vote_generator_delay, [this]() { return this->hashes.size () >= 12; }); + if (hashes.size () >= config.vote_generator_threshold && hashes.size () < 12) { - condition.wait_for (lock, node.config.vote_generator_delay, [this]() { return this->hashes.size () >= 12; }); + condition.wait_for (lock, config.vote_generator_delay, [this]() { return this->hashes.size () >= 12; }); } if (!hashes.empty ()) { diff --git a/nano/node/voting.hpp b/nano/node/voting.hpp index b98acba6..66edd70b 100644 --- a/nano/node/voting.hpp +++ b/nano/node/voting.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include #include @@ -8,35 +8,45 @@ #include #include #include -#include #include -#include #include #include #include +#include namespace nano { -class node; +class block_store; +class network; +class node_config; +class vote_processor; +class votes_cache; +class wallets; + class vote_generator final { public: - vote_generator (nano::node &); + vote_generator (nano::node_config & config_a, nano::block_store & store_a, nano::wallets & wallets_a, nano::vote_processor & vote_processor_a, nano::votes_cache & votes_cache_a, nano::network & network_a); void add (nano::block_hash const &); void stop (); private: void run (); void send (nano::unique_lock &); - nano::node & node; + nano::node_config & config; + nano::block_store & store; + nano::wallets & wallets; + nano::vote_processor & vote_processor; + nano::votes_cache & votes_cache; + nano::network & network; std::mutex mutex; nano::condition_variable condition; std::deque hashes; nano::network_params network_params; bool stopped{ false }; bool started{ false }; - boost::thread thread; + std::thread thread; friend std::unique_ptr collect_seq_con_info (vote_generator & vote_generator, const std::string & name); }; diff --git a/nano/node/wallet.cpp b/nano/node/wallet.cpp index 9fcccff6..90b73258 100644 --- a/nano/node/wallet.cpp +++ b/nano/node/wallet.cpp @@ -1,12 +1,15 @@ #include +#include #include +#include #include #include #include -#include #include +#include #include +#include #include diff --git a/nano/node/wallet.hpp b/nano/node/wallet.hpp index 7581f145..a0e3aba3 100644 --- a/nano/node/wallet.hpp +++ b/nano/node/wallet.hpp @@ -1,15 +1,14 @@ #pragma once -#include #include #include #include #include #include -#include - +#include #include +#include #include namespace nano @@ -220,7 +219,7 @@ public: nano::mdb_env & env; std::atomic stopped; std::shared_ptr watcher; - boost::thread thread; + std::thread thread; static nano::uint128_t const generate_priority; static nano::uint128_t const high_priority; std::atomic reps_count{ 0 }; diff --git a/nano/node/websocket.cpp b/nano/node/websocket.cpp index bfa77494..db72d191 100644 --- a/nano/node/websocket.cpp +++ b/nano/node/websocket.cpp @@ -1,4 +1,9 @@ -#include +#include +#include +#include +#include +#include +#include #include #include @@ -7,13 +12,13 @@ #include #include -nano::websocket::confirmation_options::confirmation_options (nano::node & node_a) : -node (node_a) +nano::websocket::confirmation_options::confirmation_options (nano::wallets & wallets_a) : +wallets (wallets_a) { } -nano::websocket::confirmation_options::confirmation_options (boost::property_tree::ptree const & options_a, nano::node & node_a) : -node (node_a) +nano::websocket::confirmation_options::confirmation_options (boost::property_tree::ptree const & options_a, nano::wallets & wallets_a, nano::logger_mt & logger_a) : +wallets (wallets_a) { // Non-account filtering options include_block = options_a.get ("include_block", true); @@ -52,7 +57,7 @@ node (node_a) if (!include_block) { - node.logger.always_log ("Websocket: Filtering option \"all_local_accounts\" requires that \"include_block\" is set to true to be effective"); + logger_a.always_log ("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")); @@ -69,19 +74,19 @@ node (node_a) } else { - node.logger.always_log ("Websocket: invalid account provided for filtering blocks: ", account_l.second.data ()); + logger_a.always_log ("Websocket: invalid account provided for filtering blocks: ", account_l.second.data ()); } } if (!include_block) { - node.logger.always_log ("Websocket: Filtering option \"accounts\" requires that \"include_block\" is set to true to be effective"); + logger_a.always_log ("Websocket: Filtering option \"accounts\" requires that \"include_block\" is set to true to be effective"); } } // Warn the user if the options resulted in an empty filter if (has_account_filtering_options && !all_local_accounts && accounts.empty ()) { - node.logger.always_log ("Websocket: provided options resulted in an empty block confirmation filter"); + logger_a.always_log ("Websocket: provided options resulted in an empty block confirmation filter"); } } @@ -110,14 +115,14 @@ bool nano::websocket::confirmation_options::should_filter (nano::websocket::mess auto source_text_l (message_a.contents.get ("message.account")); if (all_local_accounts) { - auto transaction_l (node.wallets.tx_begin_read ()); + auto transaction_l (wallets.tx_begin_read ()); nano::account source_l (0), destination_l (0); auto decode_source_ok_l (!source_l.decode_account (source_text_l)); auto decode_destination_ok_l (!destination_l.decode_account (destination_opt_l.get ())); (void)decode_source_ok_l; (void)decode_destination_ok_l; assert (decode_source_ok_l && decode_destination_ok_l); - if (node.wallets.exists (transaction_l, source_l) || node.wallets.exists (transaction_l, destination_l)) + if (wallets.exists (transaction_l, source_l) || wallets.exists (transaction_l, destination_l)) { should_filter_account = false; } @@ -131,8 +136,7 @@ bool nano::websocket::confirmation_options::should_filter (nano::websocket::mess return should_filter_conf_type_l || should_filter_account; } -nano::websocket::vote_options::vote_options (boost::property_tree::ptree const & options_a, nano::node & node_a) : -node (node_a) +nano::websocket::vote_options::vote_options (boost::property_tree::ptree const & options_a, nano::logger_mt & logger_a) { auto representatives_l (options_a.get_child_optional ("representatives")); if (representatives_l) @@ -147,14 +151,14 @@ node (node_a) } else { - node.logger.always_log ("Websocket: invalid account given to filter votes: ", representative_l.second.data ()); + logger_a.always_log ("Websocket: invalid account given to filter votes: ", representative_l.second.data ()); } } } // Warn the user if the options resulted in an empty filter if (representatives.empty ()) { - node.logger.always_log ("Websocket: provided options resulted in an empty vote filter"); + logger_a.always_log ("Websocket: provided options resulted in an empty vote filter"); } } @@ -173,7 +177,7 @@ nano::websocket::session::session (nano::websocket::listener & listener_a, socke ws_listener (listener_a), ws (std::move (socket_a)), strand (ws.get_executor ()) { ws.text (true); - ws_listener.get_node ().logger.try_log ("Websocket: session started"); + ws_listener.get_logger ().try_log ("Websocket: session started"); } nano::websocket::session::~session () @@ -198,14 +202,14 @@ void nano::websocket::session::handshake () } else { - this_l->ws_listener.get_node ().logger.always_log ("Websocket: handshake failed: ", ec.message ()); + this_l->ws_listener.get_logger ().always_log ("Websocket: handshake failed: ", ec.message ()); } }); } void nano::websocket::session::close () { - ws_listener.get_node ().logger.try_log ("Websocket: session closing"); + ws_listener.get_logger ().try_log ("Websocket: session closing"); auto this_l (shared_from_this ()); // clang-format off @@ -290,12 +294,12 @@ void nano::websocket::session::read () } catch (boost::property_tree::json_parser::json_parser_error const & ex) { - this_l->ws_listener.get_node ().logger.try_log ("Websocket: json parsing failed: ", ex.what ()); + this_l->ws_listener.get_logger ().try_log ("Websocket: json parsing failed: ", ex.what ()); } } else if (ec != boost::asio::error::eof) { - this_l->ws_listener.get_node ().logger.try_log ("Websocket: read failed: ", ec.message ()); + this_l->ws_listener.get_logger ().try_log ("Websocket: read failed: ", ec.message ()); } })); }); @@ -394,11 +398,11 @@ void nano::websocket::session::handle_message (boost::property_tree::ptree const std::unique_ptr options_l{ nullptr }; if (options_text_l && topic_l == nano::websocket::topic::confirmation) { - options_l = std::make_unique (options_text_l.get (), ws_listener.get_node ()); + options_l = std::make_unique (options_text_l.get (), ws_listener.get_wallets (), ws_listener.get_logger ()); } else if (options_text_l && topic_l == nano::websocket::topic::vote) { - options_l = std::make_unique (options_text_l.get (), ws_listener.get_node ()); + options_l = std::make_unique (options_text_l.get (), ws_listener.get_logger ()); } else { @@ -408,12 +412,12 @@ void nano::websocket::session::handle_message (boost::property_tree::ptree const if (existing != subscriptions.end ()) { existing->second = std::move (options_l); - ws_listener.get_node ().logger.always_log ("Websocket: updated subscription to topic: ", from_topic (topic_l)); + ws_listener.get_logger ().always_log ("Websocket: updated subscription to topic: ", from_topic (topic_l)); } else { subscriptions.insert (std::make_pair (topic_l, std::move (options_l))); - ws_listener.get_node ().logger.always_log ("Websocket: new subscription to topic: ", from_topic (topic_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; @@ -423,7 +427,7 @@ void nano::websocket::session::handle_message (boost::property_tree::ptree const nano::lock_guard lk (subscriptions_mutex); if (subscriptions.erase (topic_l)) { - ws_listener.get_node ().logger.always_log ("Websocket: removed subscription to topic: ", from_topic (topic_l)); + ws_listener.get_logger ().always_log ("Websocket: removed subscription to topic: ", from_topic (topic_l)); ws_listener.decrease_subscriber_count (topic_l); } action_succeeded = true; @@ -457,10 +461,11 @@ void nano::websocket::listener::stop () sessions.clear (); } -nano::websocket::listener::listener (nano::node & node_a, boost::asio::ip::tcp::endpoint endpoint_a) : -node (node_a), -acceptor (node_a.io_ctx), -socket (node_a.io_ctx) +nano::websocket::listener::listener (nano::logger_mt & logger_a, nano::wallets & wallets_a, boost::asio::io_context & io_ctx_a, boost::asio::ip::tcp::endpoint endpoint_a) : +logger (logger_a), +wallets (wallets_a), +acceptor (io_ctx_a), +socket (io_ctx_a) { try { @@ -471,7 +476,7 @@ socket (node_a.io_ctx) } catch (std::exception const & ex) { - node.logger.always_log ("Websocket: listen failed: ", ex.what ()); + logger.always_log ("Websocket: listen failed: ", ex.what ()); } } @@ -496,7 +501,7 @@ void nano::websocket::listener::on_accept (boost::system::error_code ec) { if (ec) { - node.logger.always_log ("Websocket: accept failed: ", ec.message ()); + logger.always_log ("Websocket: accept failed: ", ec.message ()); } else { @@ -531,7 +536,7 @@ void nano::websocket::listener::broadcast_confirmation (std::shared_ptrsubscriptions.find (nano::websocket::topic::confirmation)); if (subscription != session_ptr->subscriptions.end ()) { - nano::websocket::confirmation_options default_options (node); + nano::websocket::confirmation_options default_options (wallets); auto conf_options (dynamic_cast (subscription->second.get ())); if (conf_options == nullptr) { diff --git a/nano/node/websocket.hpp b/nano/node/websocket.hpp index ea262784..603bb5bb 100644 --- a/nano/node/websocket.hpp +++ b/nano/node/websocket.hpp @@ -1,21 +1,16 @@ #pragma once -#include -#include +#include +#include #include #include #include -#include -#include #include -#include -#include #include #include #include -#include #include #include #include @@ -31,7 +26,10 @@ using socket_type = boost::asio::basic_stream_socket representatives; }; @@ -243,7 +240,7 @@ namespace websocket class listener final : public std::enable_shared_from_this { public: - listener (nano::node & node_a, boost::asio::ip::tcp::endpoint endpoint_a); + listener (nano::logger_mt & logger_a, nano::wallets & wallets_a, boost::asio::io_context & io_ctx_a, boost::asio::ip::tcp::endpoint endpoint_a); /** Start accepting connections */ void run (); @@ -259,9 +256,14 @@ namespace websocket /** Broadcast \p message to all session subscribing to the message topic. */ void broadcast (nano::websocket::message message_a); - nano::node & get_node () const + nano::logger_mt & get_logger () const { - return node; + return logger; + } + + nano::wallets & get_wallets () const + { + return wallets; } /** @@ -287,7 +289,8 @@ namespace websocket /** Removes from subscription count of a specific topic*/ void decrease_subscriber_count (nano::websocket::topic const & topic_a); - nano::node & node; + nano::logger_mt & logger; + nano::wallets & wallets; boost::asio::ip::tcp::acceptor acceptor; socket_type socket; std::mutex sessions_mutex; diff --git a/nano/node/websocketconfig.cpp b/nano/node/websocketconfig.cpp index 7ce933a5..6cd91574 100644 --- a/nano/node/websocketconfig.cpp +++ b/nano/node/websocketconfig.cpp @@ -1,16 +1,18 @@ +#include #include #include #include nano::websocket::config::config () : -port (network_constants.default_websocket_port) +port (network_constants.default_websocket_port), +address (boost::asio::ip::address_v6::loopback ().to_string ()) { } nano::error nano::websocket::config::serialize_toml (nano::tomlconfig & toml) const { toml.put ("enable", enabled, "Enable or disable WebSocket server.\ntype:bool"); - toml.put ("address", address.to_string (), "WebSocket server bind address.\ntype:string,ip"); + toml.put ("address", address, "WebSocket server bind address.\ntype:string,ip"); toml.put ("port", port, "WebSocket server listening port.\ntype:uint16"); return toml.get_error (); } @@ -18,7 +20,9 @@ nano::error nano::websocket::config::serialize_toml (nano::tomlconfig & toml) co nano::error nano::websocket::config::deserialize_toml (nano::tomlconfig & toml) { toml.get ("enable", enabled); - toml.get ("address", address); + boost::asio::ip::address_v6 address_l; + toml.get_optional ("address", address_l, boost::asio::ip::address_v6::loopback ()); + address = address_l.to_string (); toml.get ("port", port); return toml.get_error (); } @@ -26,7 +30,7 @@ nano::error nano::websocket::config::deserialize_toml (nano::tomlconfig & toml) nano::error nano::websocket::config::serialize_json (nano::jsonconfig & json) const { json.put ("enable", enabled); - json.put ("address", address.to_string ()); + json.put ("address", address); json.put ("port", port); return json.get_error (); } @@ -34,7 +38,9 @@ nano::error nano::websocket::config::serialize_json (nano::jsonconfig & json) co nano::error nano::websocket::config::deserialize_json (nano::jsonconfig & json) { json.get ("enable", enabled); - json.get_required ("address", address); + boost::asio::ip::address_v6 address_l; + json.get_required ("address", address_l, boost::asio::ip::address_v6::loopback ()); + address = address_l.to_string (); json.get ("port", port); return json.get_error (); } diff --git a/nano/node/websocketconfig.hpp b/nano/node/websocketconfig.hpp index de994b10..f8b9eeef 100644 --- a/nano/node/websocketconfig.hpp +++ b/nano/node/websocketconfig.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include @@ -22,7 +21,7 @@ namespace websocket nano::network_constants network_constants; bool enabled{ false }; uint16_t port; - boost::asio::ip::address_v6 address{ boost::asio::ip::address_v6::loopback () }; + std::string address; }; } } diff --git a/nano/node/write_database_queue.hpp b/nano/node/write_database_queue.hpp index 59c9c9cf..b2657c00 100644 --- a/nano/node/write_database_queue.hpp +++ b/nano/node/write_database_queue.hpp @@ -1,5 +1,7 @@ #pragma once +#include + #include #include #include diff --git a/nano/qt_system/entry.cpp b/nano/qt_system/entry.cpp index ef11cd66..92092743 100644 --- a/nano/qt_system/entry.cpp +++ b/nano/qt_system/entry.cpp @@ -1,9 +1,12 @@ #include #include +#include #include #include #include +#include + #include int main (int argc, char ** argv) diff --git a/nano/rpc/rpc.cpp b/nano/rpc/rpc.cpp index 42e82278..5cfdebc3 100644 --- a/nano/rpc/rpc.cpp +++ b/nano/rpc/rpc.cpp @@ -1,9 +1,12 @@ +#include #include #include #include #include +#include + #ifdef NANO_SECURE_RPC #include #endif @@ -28,7 +31,7 @@ nano::rpc::~rpc () void nano::rpc::start () { - auto endpoint (boost::asio::ip::tcp::endpoint (config.address, config.port)); + auto endpoint (boost::asio::ip::tcp::endpoint (boost::asio::ip::make_address_v6 (config.address), config.port)); if (!endpoint.address ().is_loopback () && config.enable_control) { auto warning = boost::str (boost::format ("WARNING: control-level RPCs are enabled on non-local address %1%, potentially allowing wallet access outside local computer") % endpoint.address ().to_string ()); diff --git a/nano/rpc/rpc.hpp b/nano/rpc/rpc.hpp index 7949dee3..838c642e 100644 --- a/nano/rpc/rpc.hpp +++ b/nano/rpc/rpc.hpp @@ -1,10 +1,18 @@ #pragma once -#include +#include #include #include #include +namespace boost +{ +namespace asio +{ + class io_context; +} +} + namespace nano { class rpc_handler_interface; diff --git a/nano/rpc/rpc_connection.cpp b/nano/rpc/rpc_connection.cpp index 54c75b7d..ba665d77 100644 --- a/nano/rpc/rpc_connection.cpp +++ b/nano/rpc/rpc_connection.cpp @@ -1,5 +1,8 @@ -#include +#include +#include +#include #include +#include #include #include diff --git a/nano/rpc/rpc_connection.hpp b/nano/rpc/rpc_connection.hpp index 50ab9bf9..7f49203c 100644 --- a/nano/rpc/rpc_connection.hpp +++ b/nano/rpc/rpc_connection.hpp @@ -1,13 +1,11 @@ #pragma once -#include -#include -#include -#include +#include +#include +#include +#include #include -#include -#include #include diff --git a/nano/rpc/rpc_handler.cpp b/nano/rpc/rpc_handler.cpp index 2ad08b9b..5c6c201b 100644 --- a/nano/rpc/rpc_handler.cpp +++ b/nano/rpc/rpc_handler.cpp @@ -5,7 +5,6 @@ #include #include -#include #include #include diff --git a/nano/rpc/rpc_handler.hpp b/nano/rpc/rpc_handler.hpp index 3ef400b3..47fc6f8e 100644 --- a/nano/rpc/rpc_handler.hpp +++ b/nano/rpc/rpc_handler.hpp @@ -4,7 +4,6 @@ #include #include -#include namespace nano { diff --git a/nano/rpc/rpc_request_processor.cpp b/nano/rpc/rpc_request_processor.cpp index f2de12cb..889a083b 100644 --- a/nano/rpc/rpc_request_processor.cpp +++ b/nano/rpc/rpc_request_processor.cpp @@ -1,9 +1,12 @@ #include #include +#include #include +#include + nano::rpc_request_processor::rpc_request_processor (boost::asio::io_context & io_ctx, nano::rpc_config & rpc_config) : -ipc_address (rpc_config.rpc_process.ipc_address.to_string ()), +ipc_address (rpc_config.rpc_process.ipc_address), ipc_port (rpc_config.rpc_process.ipc_port), thread ([this]() { nano::thread_role::set (nano::thread_role::name::rpc_request_processor); diff --git a/nano/rpc/rpc_request_processor.hpp b/nano/rpc/rpc_request_processor.hpp index 42760d63..38ced420 100644 --- a/nano/rpc/rpc_request_processor.hpp +++ b/nano/rpc/rpc_request_processor.hpp @@ -1,15 +1,11 @@ #pragma once -#include #include #include #include -#include #include -#include -#include -#include +#include namespace nano { diff --git a/nano/rpc/rpc_secure.cpp b/nano/rpc/rpc_secure.cpp index b404d491..0e27844d 100644 --- a/nano/rpc/rpc_secure.cpp +++ b/nano/rpc/rpc_secure.cpp @@ -4,6 +4,8 @@ #include #include +#include + bool nano::rpc_secure::on_verify_certificate (bool preverified, boost::asio::ssl::verify_context & ctx) { X509_STORE_CTX * cts = ctx.native_handle (); @@ -100,8 +102,8 @@ void nano::rpc_secure::load_certs (boost::asio::ssl::context & context_a) } } -nano::rpc_secure::rpc_secure (boost::asio::io_service & service_a, nano::rpc_config const & config_a, nano::rpc_handler_interface & rpc_handler_interface_a) : -rpc (service_a, config_a, rpc_handler_interface_a), +nano::rpc_secure::rpc_secure (boost::asio::io_context & context_a, nano::rpc_config const & config_a, nano::rpc_handler_interface & rpc_handler_interface_a) : +rpc (context_a, config_a, rpc_handler_interface_a), ssl_context (boost::asio::ssl::context::tlsv12_server) { load_certs (ssl_context); diff --git a/nano/rpc/rpc_secure.hpp b/nano/rpc/rpc_secure.hpp index 336827f5..26016145 100644 --- a/nano/rpc/rpc_secure.hpp +++ b/nano/rpc/rpc_secure.hpp @@ -2,7 +2,14 @@ #include #include -#include + +namespace boost +{ +namespace asio +{ + class io_context; +} +} namespace nano { @@ -12,7 +19,7 @@ namespace nano class rpc_secure : public rpc { public: - rpc_secure (boost::asio::io_service & service_a, nano::rpc_config const & config_a, nano::rpc_handler_interface & rpc_handler_interface_a); + rpc_secure (boost::asio::io_context & context_a, nano::rpc_config const & config_a, nano::rpc_handler_interface & rpc_handler_interface_a); /** Starts accepting connections */ void accept () override; diff --git a/nano/rpc_test/rpc.cpp b/nano/rpc_test/rpc.cpp index 35638b0f..4c6383d3 100644 --- a/nano/rpc_test/rpc.cpp +++ b/nano/rpc_test/rpc.cpp @@ -1,7 +1,8 @@ +#include +#include #include -#include #include -#include +#include #include #include #include @@ -11,7 +12,8 @@ #include -#include +#include +#include #include @@ -2419,7 +2421,7 @@ TEST (rpc, peers) auto port = nano::get_available_port (); system.add_node (nano::node_config (port, system.logging)); scoped_io_thread_name_change scoped_thread_name_io; - nano::endpoint endpoint (boost::asio::ip::address_v6::from_string ("fc00::1"), 4000); + nano::endpoint endpoint (boost::asio::ip::make_address_v6 ("fc00::1"), 4000); node->network.udp_channels.insert (endpoint, node->network_params.protocol.protocol_version); nano::node_rpc_config node_rpc_config; nano::ipc::ipc_server ipc_server (*node, node_rpc_config); @@ -2453,7 +2455,7 @@ TEST (rpc, peers_node_id) auto port = nano::get_available_port (); system.add_node (nano::node_config (port, system.logging)); scoped_io_thread_name_change scoped_thread_name_io; - nano::endpoint endpoint (boost::asio::ip::address_v6::from_string ("fc00::1"), 4000); + nano::endpoint endpoint (boost::asio::ip::make_address_v6 ("fc00::1"), 4000); node->network.udp_channels.insert (endpoint, node->network_params.protocol.protocol_version); nano::node_rpc_config node_rpc_config; nano::ipc::ipc_server ipc_server (*node, node_rpc_config); @@ -7218,12 +7220,12 @@ TEST (rpc, in_process) TEST (rpc_config, serialization) { nano::rpc_config config1; - config1.address = boost::asio::ip::address_v6::any (); + config1.address = boost::asio::ip::address_v6::any ().to_string (); config1.port = 10; config1.enable_control = true; config1.max_json_depth = 10; config1.rpc_process.io_threads = 2; - config1.rpc_process.ipc_address = boost::asio::ip::address_v6::any (); + config1.rpc_process.ipc_address = boost::asio::ip::address_v6::any ().to_string (); config1.rpc_process.ipc_port = 2000; config1.rpc_process.num_ipc_connections = 99; nano::jsonconfig tree; diff --git a/nano/secure/CMakeLists.txt b/nano/secure/CMakeLists.txt index 2dda6242..87c8cc34 100644 --- a/nano/secure/CMakeLists.txt +++ b/nano/secure/CMakeLists.txt @@ -35,11 +35,12 @@ add_library (secure ${PLATFORM_SECURE_SOURCE} ${CMAKE_BINARY_DIR}/bootstrap_weights_live.cpp ${CMAKE_BINARY_DIR}/bootstrap_weights_beta.cpp + blockstore.hpp + blockstore.cpp + blockstore_partial.hpp + buffer.hpp common.hpp common.cpp - blockstore.hpp - blockstore_partial.hpp - blockstore.cpp epoch.hpp epoch.cpp ledger.hpp diff --git a/nano/secure/blockstore.cpp b/nano/secure/blockstore.cpp index eec99493..c865952c 100644 --- a/nano/secure/blockstore.cpp +++ b/nano/secure/blockstore.cpp @@ -1,7 +1,7 @@ +#include #include #include -#include nano::block_sideband::block_sideband (nano::block_type type_a, nano::account const & account_a, nano::block_hash const & successor_a, nano::amount const & balance_a, uint64_t height_a, uint64_t timestamp_a, nano::epoch epoch_a) : type (type_a), diff --git a/nano/secure/blockstore.hpp b/nano/secure/blockstore.hpp index c7abd3fc..375cd619 100644 --- a/nano/secure/blockstore.hpp +++ b/nano/secure/blockstore.hpp @@ -1,11 +1,11 @@ #pragma once #include -#include #include #include #include #include +#include #include #include @@ -516,7 +516,7 @@ public: impl->fill (current); return *this; } - nano::store_iterator & operator= (nano::store_iterator && other_a) + nano::store_iterator & operator= (nano::store_iterator && other_a) noexcept { impl = std::move (other_a.impl); current = std::move (other_a.current); diff --git a/nano/secure/blockstore_partial.hpp b/nano/secure/blockstore_partial.hpp index 2fab67ad..4e8ea843 100644 --- a/nano/secure/blockstore_partial.hpp +++ b/nano/secure/blockstore_partial.hpp @@ -2,6 +2,9 @@ #include #include +#include + +#include namespace nano { diff --git a/nano/secure/buffer.hpp b/nano/secure/buffer.hpp new file mode 100644 index 00000000..d1a45117 --- /dev/null +++ b/nano/secure/buffer.hpp @@ -0,0 +1,13 @@ +#pragma once + +#include +#include +#include + +#include + +namespace nano +{ +using bufferstream = boost::iostreams::stream_buffer>; +using vectorstream = boost::iostreams::stream_buffer>>; +} diff --git a/nano/secure/common.cpp b/nano/secure/common.cpp index f693260f..a92a3511 100644 --- a/nano/secure/common.cpp +++ b/nano/secure/common.cpp @@ -5,10 +5,12 @@ #include #include +#include + #include #include +#include -#include #include #include diff --git a/nano/secure/common.hpp b/nano/secure/common.hpp index cc7e82cf..c641cfbb 100644 --- a/nano/secure/common.hpp +++ b/nano/secure/common.hpp @@ -7,11 +7,11 @@ #include #include #include -#include #include -#include -#include +#include +#include +#include #include diff --git a/nano/secure/ledger.hpp b/nano/secure/ledger.hpp index d8b6c854..2930a9a0 100644 --- a/nano/secure/ledger.hpp +++ b/nano/secure/ledger.hpp @@ -1,13 +1,15 @@ #pragma once -#include #include #include +#include + namespace nano { class block_store; class stat; +class write_transaction; using tally_t = std::map, std::greater>; class ledger final diff --git a/nano/secure/plat/windows/working.cpp b/nano/secure/plat/windows/working.cpp index 07e005e2..958103e8 100644 --- a/nano/secure/plat/windows/working.cpp +++ b/nano/secure/plat/windows/working.cpp @@ -1,5 +1,7 @@ #include +#include + #include namespace nano diff --git a/nano/secure/utility.cpp b/nano/secure/utility.cpp index d4a16ac7..39cb5534 100644 --- a/nano/secure/utility.cpp +++ b/nano/secure/utility.cpp @@ -2,6 +2,8 @@ #include #include +#include + static std::vector all_unique_paths; boost::filesystem::path nano::working_path (bool legacy) diff --git a/nano/secure/utility.hpp b/nano/secure/utility.hpp index 716f0320..16823936 100644 --- a/nano/secure/utility.hpp +++ b/nano/secure/utility.hpp @@ -1,24 +1,11 @@ #pragma once -#include -#include - #include -#include -#include -#include -#include - -#include -#include -#include -#include +#include namespace nano { -using bufferstream = boost::iostreams::stream_buffer>; -using vectorstream = boost::iostreams::stream_buffer>>; // OS-specific way of finding a path to a home directory. boost::filesystem::path working_path (bool = false); // Function to migrate working_path() from above from RaiBlocks to Nano diff --git a/nano/secure/versioning.hpp b/nano/secure/versioning.hpp index f9346cb8..6c29effa 100644 --- a/nano/secure/versioning.hpp +++ b/nano/secure/versioning.hpp @@ -2,7 +2,6 @@ #include #include -#include struct MDB_val; diff --git a/nano/slow_test/node.cpp b/nano/slow_test/node.cpp index 966ac353..bb0ebd5c 100644 --- a/nano/slow_test/node.cpp +++ b/nano/slow_test/node.cpp @@ -1,12 +1,12 @@ #include #include +#include +#include #include #include #include -#include - using namespace std::chrono_literals; TEST (system, generate_mass_activity)