diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt index ff8bf24c..6dfccae3 100644 --- a/external/CMakeLists.txt +++ b/external/CMakeLists.txt @@ -81,5 +81,3 @@ add_subdirectory(db_drivers) add_subdirectory(easylogging++) # fmt is shipped as subtree add_subdirectory(fmt) -# activate extended color output for fmt -add_definitions(-DFMT_EXTENDED_COLORS) diff --git a/src/address_validator/address_validator.cpp b/src/address_validator/address_validator.cpp index ebea203f..8946572e 100644 --- a/src/address_validator/address_validator.cpp +++ b/src/address_validator/address_validator.cpp @@ -42,6 +42,9 @@ // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // +#define GULPS_CAT_MAJOR "addr_val" +#include "common/gulps.hpp" + #include "address_validator/address_validator.h" #include "string_tools.h" #include "cryptonote_basic/cryptonote_basic_impl.h" @@ -98,19 +101,19 @@ bool address_validator::evaluate_address_attributes(const std::string &net_type, bool valid = false; if(net_type == "mainnet") { - valid = get_account_address_from_str(attr.info, addr_str, true); + valid = get_account_address_from_str(attr.info, addr_str); attr.network = valid ? "mainnet" : ""; attr.nettype = MAINNET; } else if(net_type == "testnet") { - valid = get_account_address_from_str(attr.info, addr_str, true); + valid = get_account_address_from_str(attr.info, addr_str); attr.network = valid ? "testnet" : ""; attr.nettype = TESTNET; } else if(net_type == "stagenet") { - valid = get_account_address_from_str(attr.info, addr_str, true); + valid = get_account_address_from_str(attr.info, addr_str); attr.network = valid ? "stagenet" : ""; attr.nettype = STAGENET; } @@ -125,7 +128,11 @@ void address_validator::init_options( { namespace po = boost::program_options; - desc.add_options()("network,n", po::value(&m_network)->default_value("auto"), "network type (auto, mainnet, testnet, stagenet)")("filename,f", po::value(&m_filename), "json file name, if not set result is printed to terminal")("human", po::value(&m_human)->zero_tokens()->default_value(false)->default_value(false), "human readable output")("address", po::value>(&m_address_strs), "ryo-currency address"); + desc.add_options() + ("network,n", po::value(&m_network)->default_value("auto"), "network type (auto, mainnet, testnet, stagenet)") + ("filename,f", po::value(&m_filename), "json file name, if not set result is printed to terminal") + ("human", po::value(&m_human)->zero_tokens()->default_value(false)->default_value(false), "human readable output") + ("address", po::value>(&m_address_strs), "ryo-currency address"); pos_option.add("address", -1); } @@ -134,14 +141,14 @@ bool address_validator::validate_options() { if(m_address_strs.empty()) { - MERROR("No address given."); + GULPS_ERROR("No address given."); return 1; } std::vector networks = {"auto", "mainnet", "testnet", "stagenet"}; if(std::find(networks.begin(), networks.end(), m_network) == networks.end()) { - MERROR("Invalid/Unknown network type " << m_network); + GULPS_ERROR("Invalid/Unknown network type {}.", m_network); return 2; } return 0; @@ -192,10 +199,18 @@ int main(int argc, char *argv[]) po::options_description desc("Validate RYO/SUMOKOIN addresses and show properties\n\n" "ryo-address-validator [OPTIONS] WALLET_ADDRESS [WALLET_ADDRESS...]\n\n" "OPTIONS"); + po::positional_options_description pos_option; desc.add_options()("help,h", "print help message and exit"); + gulps::inst().set_thread_tag("MAIN"); + + // We won't replace the custom output writer here, so just direct **our** errors to console + std::unique_ptr out(new gulps::gulps_print_output(true, fmt::color::white)); + out->add_filter([](const gulps::message& msg) -> bool { return msg.cat_major == GULPS_CAT_MAJOR && msg.lvl == gulps::LEVEL_ERROR; }); + gulps::inst().add_output(std::move(out)); + using namespace cryptonote; address_validator validator{}; diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index c759f908..82f9d635 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -54,7 +54,8 @@ set(common_sources password.cpp perf_timer.cpp threadpool.cpp - updates.cpp) + updates.cpp + string.cpp) if (STACK_TRACE) list(APPEND common_sources stack_trace.cpp) @@ -63,6 +64,8 @@ endif() set(common_headers) set(common_private_headers + gulps.hpp + string.hpp apply_permutation.h base58.h boost_serialization_helper.h @@ -104,9 +107,13 @@ target_link_libraries(common ${Boost_THREAD_LIBRARY} ${Boost_REGEX_LIBRARY} ${Boost_CHRONO_LIBRARY} + fmt::fmt-header-only PRIVATE ${OPENSSL_LIBRARIES} ${EXTRA_LIBRARIES}) +# activate extended color output for fmt +target_compile_definitions(common PUBLIC -DFMT_EXTENDED_COLORS) + #monero_install_headers(common # ${common_headers}) diff --git a/src/common/gulps.hpp b/src/common/gulps.hpp new file mode 100644 index 00000000..67447876 --- /dev/null +++ b/src/common/gulps.hpp @@ -0,0 +1,342 @@ +// Copyright (c) 2018, Ryo Currency Project +// +// Portions of this file are available under BSD-3 license. Please see ORIGINAL-LICENSE for details +// All rights reserved. +// +// Authors and copyright holders give permission for following: +// +// 1. Redistribution and use in source and binary forms WITHOUT modification. +// +// 2. Modification of the source form for your own personal use. +// +// As long as the following conditions are met: +// +// 3. You must not distribute modified copies of the work to third parties. This includes +// posting the work online, or hosting copies of the modified work for download. +// +// 4. Any derivative version of this work is also covered by this license, including point 8. +// +// 5. Neither the name of the copyright holders nor the names of the authors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// 6. You agree that this licence is governed by and shall be construed in accordance +// with the laws of England and Wales. +// +// 7. You agree to submit all disputes arising out of or in connection with this licence +// to the exclusive jurisdiction of the Courts of England and Wales. +// +// Authors and copyright holders agree that: +// +// 8. This licence expires and the work covered by it is released into the +// public domain on 1st of February 2019 +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#pragma once + +#include +#include +#include +#include +#include +#include +#include "thdq.hpp" +#include "string.hpp" +#include +#include + +class gulps +{ +public: + enum level + { + LEVEL_OUTPUT_0, + LEVEL_OUTPUT_1, + LEVEL_OUTPUT_2, + LEVEL_ERROR, + LEVEL_WARN, + LEVEL_INFO, + LEVEL_DEBUG_0, + LEVEL_DEBUG_1, + LEVEL_DEBUG_2 + }; + + static inline const char* level_to_str(level lvl) + { + switch(lvl) + { + case LEVEL_OUTPUT_0: return "OUTPUT0"; + case LEVEL_OUTPUT_1: return "OUTPUT1"; + case LEVEL_OUTPUT_2: return "OUTPUT2"; + case LEVEL_ERROR: return "ERROR"; + case LEVEL_WARN: return "WARN"; + case LEVEL_INFO: return "INFO"; + case LEVEL_DEBUG_0: return "DEBUG0"; + case LEVEL_DEBUG_1: return "DEBUG1"; + case LEVEL_DEBUG_2: return "DEBUG2"; + default: return "UNKNOWN"; + } + } + + //Object handling a single long message + class message + { + public: + std::time_t time; + level lvl; + std::string cat_major; + std::string cat_minor; + std::string src_path; + int64_t src_line; + std::string thread_id; + std::string text; + fmt::color clr; + + message(level lvl, const char* major, const char* minor, const char* path, int64_t line, std::string&& text, fmt::color clr = fmt::color::white) : + time(std::time(nullptr)), lvl(lvl), cat_major(major), cat_minor(minor), src_path(path), src_line(line), + thread_id(gulps::inst().get_thread_tag()), text(std::move(text)), clr(clr) + { + } + + std::string print_message(bool inc_text = true) const + { + std::string out = fmt::format("{:%Y-%m-%d %H:%M:%S} {} [{}] {}.{} {}:{} ", fmt::localtime(time), + level_to_str(lvl), thread_id, cat_major, cat_minor, src_path, src_line); + + if(inc_text) + out += print_text(); + + return out; + } + + std::string print_text() const + { + std::string out = text; + if(text.back() != '\n') + out += '\n'; + return out; + } + + message(message&& ) = default; + message& operator=(message&& ) = default; + message(const message& ) = default; + message& operator=(const message& ) = default; + }; + + // Function pointers are mariginally more efficient than functors here + // NB Lambdas must not capture to be convertible to a function ptr + typedef bool (*filter_fun)(const message&); + + class gulps_output + { + public: + gulps_output() = default; + virtual ~gulps_output() = default; + virtual void log_message(const message& msg) = 0; + + // This is filtered call + bool log(const message& msg) + { + bool result = false; + for(filter_fun filter : filters) + { + if(filter(msg)) + { + result = true; + break; + } + } + + if(result) + log_message(msg); + + return result; + } + + void add_filter(filter_fun filter) { filters.push_back(filter); }; + + private: + gulps_output(gulps_output&& ) = delete; + gulps_output& operator=(gulps_output&& ) = delete; + gulps_output(gulps_output& ) = delete; + gulps_output& operator=(gulps_output& ) = delete; + + std::vector filters; + }; + + class gulps_print_output : public gulps_output + { + public: + gulps_print_output(bool text_only, fmt::color hdr_color) : text_only(text_only), hdr_color(hdr_color) {} + + void log_message(const message& msg) override + { + if(!text_only) + fmt::print(hdr_color, msg.print_message(false)); + fmt::print(msg.clr, msg.print_text()); + } + + protected: + bool text_only; + fmt::color hdr_color; + }; + + //Class handling synchronous file logging. + class gulps_file_output : public gulps_output + { + public: + gulps_file_output(const std::string& name) : fname(name) + { + output_file.open(fname, std::ios::out | std::ios::app | std::ios::binary); // may throw + } + + void log_message(const message& msg) override + { + write_output(msg); + } + + ~gulps_file_output() + { + log_message(message(LEVEL_DEBUG_2, "log_shutdown", fname.c_str(), __FILE__, __LINE__, "Log file shutting down.")); + output_file.close(); + } + + protected: + inline void write_output(const message& msg) + { + try + { + output_file << msg.print_message(true); + output_file.flush(); + } + catch(const std::exception& ex) + { + std::cout << "!!! PANIC, error writing to a log file! Your disk is probably full! " << ex.what() << std::endl; + } + } + + std::string fname; + std::ofstream output_file; + }; + + //Class handling async logging. Async logging is thread-safe and preserves temporal order + class gulps_async_file_output : public gulps_file_output + { + public: + gulps_async_file_output(const std::string& name) : + gulps_file_output(name), thd(&gulps_async_file_output::output_main, this) + { + } + + void log_message(const message& msg) override + { + msg_q.push(msg); + } + + void output_main() + { + while(msg_q.wait_for_pop()) + { + message msg = msg_q.pop(); + write_output(msg); + } + } + + ~gulps_async_file_output() + { + log_message(message(LEVEL_DEBUG_2, "log_shutdown", fname.c_str(), __FILE__, __LINE__, "Log thread shutting down.")); + if(thd.joinable()) + { + msg_q.set_finish_flag(); + thd.join(); + } + } + + private: + inline void write_output(const message& msg) + { + try + { + output_file << msg.print_message(true); + output_file.flush(); + } + catch(const std::exception& ex) + { + std::cerr << "!!! PANIC, error writing to a log file! Your disk is probably full! " << ex.what() << std::endl; + } + } + + thdq msg_q; + std::thread thd; + }; + + gulps() {} + + inline const std::string& get_thread_tag() { return thread_tag(); } + inline void set_thread_tag(const std::string& tag) { thread_tag() = tag; } + + inline static gulps& inst() + { + static gulps inst; + return inst; + } + + inline static const gulps& cinst() + { + static const gulps& inst = gulps::inst(); + return inst; + } + + void add_output(std::unique_ptr output) { outputs.push_back(std::move(output)); }; + + void log(message&& in_msg) + { + message msg = std::move(in_msg); + + for(std::unique_ptr& out : outputs) + out->log(msg); + } + +private: + inline std::string& thread_tag() + { + static thread_local std::string thread_tag; + return thread_tag; + } + + std::list> outputs; +}; + +#define GULPS_OUTPUT(lvl, maj, min, clr, ...) gulps::inst().log(gulps::message(lvl, maj, min, __FILE__, __LINE__, fmt::format(__VA_ARGS__), clr)) +#define GULPS_CAT_ERROR(maj, min, fstr, ...) GULPS_OUTPUT(gulps::LEVEL_ERROR, maj, min, fmt::color::red, fstr, __VA_ARGS__) +#define GULPS_CAT_WARN(maj, min, fstr, ...) GULPS_OUTPUT(gulps::LEVEL_WARN, maj, min, fmt::color::orange, fstr, __VA_ARGS__) +#define GULPS_CAT_INFO(maj, min, fstr, ...) GULPS_OUTPUT(gulps::LEVEL_INFO, maj, min, fmt::color::white, fstr, __VA_ARGS__) +#define GULPS_CAT_DEBUG0(maj, min, fstr, ...) GULPS_OUTPUT(gulps::LEVEL_DEBUG_0, maj, min, fmt::color::white, fstr, __VA_ARGS__) +#define GULPS_CAT_DEBUG1(maj, min, fstr, ...) GULPS_OUTPUT(gulps::LEVEL_DEBUG_1, maj, min, fmt::color::white, fstr, __VA_ARGS__) +#define GULPS_CAT_DEBUG2(maj, min, fstr, ...) GULPS_OUTPUT(gulps::LEVEL_DEBUG_2, maj, min, fmt::color::white, fstr, __VA_ARGS__) +#define GULPS_CAT_PRINT(maj, min, clr, fstr, ...) GULPS_OUTPUT(gulps::LEVEL_OUTPUT_0, maj, min, clr, fstr, __VA_ARGS__) + +#ifndef GULPS_CAT_MAJOR +#define GULPS_CAT_MAJOR "default" +#endif + +#ifndef GULPS_CAT_MINOR +#define GULPS_CAT_MINOR "" +#endif + +#define GULPS_ERROR(...) GULPS_OUTPUT(gulps::LEVEL_ERROR, GULPS_CAT_MAJOR, GULPS_CAT_MINOR, fmt::color::red, __VA_ARGS__) +#define GULPS_WARN(fstr, ...) GULPS_OUTPUT(gulps::LEVEL_WARN, GULPS_CAT_MAJOR, GULPS_CAT_MINOR, fmt::color::orange, fstr, __VA_ARGS__) +#define GULPS_INFO(fstr, ...) GULPS_OUTPUT(gulps::LEVEL_INFO, GULPS_CAT_MAJOR, GULPS_CAT_MINOR, fmt::color::white, fstr, __VA_ARGS__) +#define GULPS_DEBUG0(fstr, ...) GULPS_OUTPUT(gulps::LEVEL_DEBUG_0, GULPS_CAT_MAJOR, GULPS_CAT_MINOR, fmt::color::white, fstr, __VA_ARGS__) +#define GULPS_DEBUG1(fstr, ...) GULPS_OUTPUT(gulps::LEVEL_DEBUG_1, GULPS_CAT_MAJOR, GULPS_CAT_MINOR, fmt::color::white, fstr, __VA_ARGS__) +#define GULPS_DEBUG2(fstr, ...) GULPS_OUTPUT(gulps::LEVEL_DEBUG_2, GULPS_CAT_MAJOR, GULPS_CAT_MINOR, fmt::color::white, fstr, __VA_ARGS__) +#define GULPS_PRINT(clr, fstr, ...) GULPS_OUTPUT(gulps::LEVEL_OUTPUT_0, GULPS_CAT_MAJOR, GULPS_CAT_MINOR, clr, fstr, __VA_ARGS__) diff --git a/src/common/string.cpp b/src/common/string.cpp new file mode 100644 index 00000000..808c9955 --- /dev/null +++ b/src/common/string.cpp @@ -0,0 +1,49 @@ +// Copyright (c) 2018, Ryo Currency Project +// +// Portions of this file are available under BSD-3 license. Please see ORIGINAL-LICENSE for details +// All rights reserved. +// +// Authors and copyright holders give permission for following: +// +// 1. Redistribution and use in source and binary forms WITHOUT modification. +// +// 2. Modification of the source form for your own personal use. +// +// As long as the following conditions are met: +// +// 3. You must not distribute modified copies of the work to third parties. This includes +// posting the work online, or hosting copies of the modified work for download. +// +// 4. Any derivative version of this work is also covered by this license, including point 8. +// +// 5. Neither the name of the copyright holders nor the names of the authors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// 6. You agree that this licence is governed by and shall be construed in accordance +// with the laws of England and Wales. +// +// 7. You agree to submit all disputes arising out of or in connection with this licence +// to the exclusive jurisdiction of the Courts of England and Wales. +// +// Authors and copyright holders agree that: +// +// 8. This licence expires and the work covered by it is released into the +// public domain on 1st of February 2019 +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +#include + +std::string operator ""_s(const char * str, size_t len) { + return std::string(str, len); +} \ No newline at end of file diff --git a/src/common/string.hpp b/src/common/string.hpp new file mode 100644 index 00000000..b44f0f14 --- /dev/null +++ b/src/common/string.hpp @@ -0,0 +1,54 @@ +// Copyright (c) 2018, Ryo Currency Project +// +// Portions of this file are available under BSD-3 license. Please see ORIGINAL-LICENSE for details +// All rights reserved. +// +// Authors and copyright holders give permission for following: +// +// 1. Redistribution and use in source and binary forms WITHOUT modification. +// +// 2. Modification of the source form for your own personal use. +// +// As long as the following conditions are met: +// +// 3. You must not distribute modified copies of the work to third parties. This includes +// posting the work online, or hosting copies of the modified work for download. +// +// 4. Any derivative version of this work is also covered by this license, including point 8. +// +// 5. Neither the name of the copyright holders nor the names of the authors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// 6. You agree that this licence is governed by and shall be construed in accordance +// with the laws of England and Wales. +// +// 7. You agree to submit all disputes arising out of or in connection with this licence +// to the exclusive jurisdiction of the Courts of England and Wales. +// +// Authors and copyright holders agree that: +// +// 8. This licence expires and the work covered by it is released into the +// public domain on 1st of February 2019 +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#pragma once + +#include + +/** convert a C string into a C++ std::string + * + * @code{cpp} + * auto foo = "Hello World!"_s; // type of foo is std::string + * @endcode + */ +std::string operator ""_s(const char * str, size_t len); \ No newline at end of file diff --git a/src/common/thdq.hpp b/src/common/thdq.hpp new file mode 100644 index 00000000..d46b68f6 --- /dev/null +++ b/src/common/thdq.hpp @@ -0,0 +1,120 @@ +// Copyright (c) 2018, Ryo Currency Project +// +// Portions of this file are available under BSD-3 license. Please see ORIGINAL-LICENSE for details +// All rights reserved. +// +// Authors and copyright holders give permission for following: +// +// 1. Redistribution and use in source and binary forms WITHOUT modification. +// +// 2. Modification of the source form for your own personal use. +// +// As long as the following conditions are met: +// +// 3. You must not distribute modified copies of the work to third parties. This includes +// posting the work online, or hosting copies of the modified work for download. +// +// 4. Any derivative version of this work is also covered by this license, including point 8. +// +// 5. Neither the name of the copyright holders nor the names of the authors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// 6. You agree that this licence is governed by and shall be construed in accordance +// with the laws of England and Wales. +// +// 7. You agree to submit all disputes arising out of or in connection with this licence +// to the exclusive jurisdiction of the Courts of England and Wales. +// +// Authors and copyright holders agree that: +// +// 8. This licence expires and the work covered by it is released into the +// public domain on 1st of February 2019 +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#pragma once + +#include +#include +#include +#include +#include + +template +class thdq +{ +public: + thdq() : lck_(mutex_, std::defer_lock) {} + + bool pop(T& item) + { + std::unique_lock mlock(mutex_); + while (queue_.empty() && !finish) { cond_.wait(mlock); } + bool ret = false; + if(!queue_.empty()) + { + item = std::move(queue_.front()); + queue_.pop(); + ret = true; + } + return ret; + } + + bool wait_for_pop() + { + lck_.lock(); + while (queue_.empty() && !finish) { cond_.wait(lck_); } + bool has_pop = !queue_.empty(); + if(!has_pop) lck_.unlock(); + return has_pop; + } + + T pop() + { + T item = std::move(queue_.front()); + queue_.pop(); + lck_.unlock(); + return item; + } + + void push(const T& item) + { + std::unique_lock mlock(mutex_); + if(finish) return; + queue_.push(item); + mlock.unlock(); + cond_.notify_one(); + } + + void push(T&& item) + { + std::unique_lock mlock(mutex_); + if(finish) return; + queue_.push(std::move(item)); + mlock.unlock(); + cond_.notify_one(); + } + + void set_finish_flag() + { + std::unique_lock mlock(mutex_); + finish = true; + cond_.notify_one(); + } + +private: + std::queue queue_; + std::mutex mutex_; + std::condition_variable cond_; + std::unique_lock lck_; + bool finish = false; +}; diff --git a/src/cryptonote_basic/cryptonote_basic_impl.cpp b/src/cryptonote_basic/cryptonote_basic_impl.cpp index b3bdaf1c..e72be2f5 100644 --- a/src/cryptonote_basic/cryptonote_basic_impl.cpp +++ b/src/cryptonote_basic/cryptonote_basic_impl.cpp @@ -47,6 +47,9 @@ #include "include_base_utils.h" using namespace epee; +#define GULPS_CAT_MAJOR "basic_util" +#include "common/gulps.hpp" + #include "common/base58.h" #include "common/dns_utils.h" #include "common/int-util.h" @@ -284,14 +287,13 @@ bool is_coinbase(const transaction &tx) } //----------------------------------------------------------------------- template -bool get_account_address_from_str(address_parse_info &info, std::string const &str, const bool silent) +bool get_account_address_from_str(address_parse_info &info, std::string const &str) { blobdata data; uint64_t prefix; if(!tools::base58::decode_addr(str, prefix, data)) { - if(!silent) - LOG_PRINT_L2("Invalid address format"); + GULPS_ERROR("Invalid address format"); return false; } @@ -321,8 +323,7 @@ bool get_account_address_from_str(address_parse_info &info, std::string const &s break; */ default: - if(!silent) - LOG_PRINT_L1("Wrong address prefix: " << prefix); + GULPS_ERROR("Wrong address prefix: "_s + std::to_string(prefix)); return false; } @@ -331,8 +332,7 @@ bool get_account_address_from_str(address_parse_info &info, std::string const &s integrated_address iadr; if(!::serialization::parse_binary(data, iadr)) { - if(!silent) - LOG_PRINT_L1("Account public address keys can't be parsed"); + GULPS_ERROR("Account public address keys can't be parsed"); return false; } info.address = iadr.adr; @@ -343,8 +343,7 @@ bool get_account_address_from_str(address_parse_info &info, std::string const &s kurz_address kadr; if(!::serialization::parse_binary(data, kadr)) { - if(!silent) - LOG_PRINT_L1("Account public address keys can't be parsed"); + GULPS_ERROR("Account public address keys can't be parsed"); return false; } @@ -355,16 +354,14 @@ bool get_account_address_from_str(address_parse_info &info, std::string const &s { if(!::serialization::parse_binary(data, info.address)) { - if(!silent) - LOG_PRINT_L1("Account public address keys can't be parsed"); + GULPS_ERROR("Account public address keys can't be parsed"); return false; } } if(!crypto::check_key(info.address.m_spend_public_key) || !crypto::check_key(info.address.m_view_public_key)) { - if(!silent) - LOG_PRINT_L1("Failed to validate address keys"); + GULPS_ERROR("Failed to validate address keys"); return false; } diff --git a/src/cryptonote_basic/cryptonote_basic_impl.h b/src/cryptonote_basic/cryptonote_basic_impl.h index c4543b54..65f139ed 100644 --- a/src/cryptonote_basic/cryptonote_basic_impl.h +++ b/src/cryptonote_basic/cryptonote_basic_impl.h @@ -178,18 +178,18 @@ inline std::string get_account_integrated_address_as_str(network_type nettype, c } template -bool get_account_address_from_str(address_parse_info &info, const std::string &str, const bool silent = false); +bool get_account_address_from_str(address_parse_info &info, const std::string &str); -inline bool get_account_address_from_str(network_type nettype, address_parse_info &info, const std::string &str, const bool silent = false) +inline bool get_account_address_from_str(network_type nettype, address_parse_info &info, const std::string &str) { switch(nettype) { case MAINNET: - return get_account_address_from_str(info, str, silent); + return get_account_address_from_str(info, str); case TESTNET: - return get_account_address_from_str(info, str, silent); + return get_account_address_from_str(info, str); case STAGENET: - return get_account_address_from_str(info, str, silent); + return get_account_address_from_str(info, str); default: return false; }