From 46fc72a1e7ea22bae389ad56162e712b341fc15e Mon Sep 17 00:00:00 2001 From: johndebord Date: Wed, 10 Jun 2020 17:44:10 +0000 Subject: [PATCH 001/124] eosio 84109ebdc36927f8b1f3afa92672359c28f1bd71 --- CMakeLists.txt | 5 +++++ CMakeModules/FindGMP.cmake | 8 +++++++- secp256k1/CMakeLists.txt | 25 +++++++++++++++++++++---- secp256k1/libsecp256k1-config.h | 21 --------------------- src/crypto/elliptic_secp256k1.cpp | 3 ++- src/crypto/private_key.cpp | 4 ++-- src/crypto/signature.cpp | 4 ++-- src/log/console_appender.cpp | 2 +- 8 files changed, 40 insertions(+), 32 deletions(-) delete mode 100644 secp256k1/libsecp256k1-config.h diff --git a/CMakeLists.txt b/CMakeLists.txt index b21fd6cea..93f06c7c2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -123,6 +123,11 @@ list(APPEND sources ${fc_headers}) setup_library( fc SOURCES ${sources} LIBRARY_TYPE STATIC DONT_INSTALL_LIBRARY ) +if(ENABLE_UNITY_BUILD) + set_target_properties(fc PROPERTIES UNITY_BUILD TRUE) +endif() + + function(detect_thread_name) include(CheckSymbolExists) list(APPEND CMAKE_REQUIRED_DEFINITIONS -D_GNU_SOURCE) diff --git a/CMakeModules/FindGMP.cmake b/CMakeModules/FindGMP.cmake index b6a402d0b..3aaa4b36d 100644 --- a/CMakeModules/FindGMP.cmake +++ b/CMakeModules/FindGMP.cmake @@ -1,3 +1,5 @@ +# This module's inputs: +# GMP_STATIC - static link GMP # This module defines: # GMP_FOUND - system has GMP lib # GMP_INCLUDE_DIR - the GMP include directory @@ -32,7 +34,11 @@ else() ) set(PREVIOUS_CMAKE_FIND_LIBRARY_SUFFIXES "${CMAKE_FIND_LIBRARY_SUFFIXES}") - set(CMAKE_FIND_LIBRARY_SUFFIXES "${CMAKE_SHARED_LIBRARY_SUFFIX}") + if(GMP_STATIC) + set(CMAKE_FIND_LIBRARY_SUFFIXES "${CMAKE_STATIC_LIBRARY_SUFFIX}") + else() + set(CMAKE_FIND_LIBRARY_SUFFIXES "${CMAKE_SHARED_LIBRARY_SUFFIX}") + endif() find_library(GMP_LIBRARIES NAMES gmp HINTS ENV GMP_LIB_DIR diff --git a/secp256k1/CMakeLists.txt b/secp256k1/CMakeLists.txt index 3be0ea4a6..5d2ab0f9e 100644 --- a/secp256k1/CMakeLists.txt +++ b/secp256k1/CMakeLists.txt @@ -1,7 +1,24 @@ -cmake_minimum_required(VERSION 3.4) -project(secp256k1) +set(GMP_USAGES "On;Auto;Off") +set(GMP_USAGE "On" CACHE STRING "libgmp usage: On: required; Auto: used if present; Off: not used") +set_property(CACHE GMP_USAGE PROPERTY STRINGS ${GMP_USAGES}) -find_package(GMP REQUIRED) +if(NOT GMP_USAGE IN_LIST GMP_USAGES) + message(FATAL_ERROR "GMP_USAGE must be set to one of: ${GMP_USAGES}") +endif() + +if(GMP_USAGE STREQUAL "On") + find_package(GMP REQUIRED) +elseif(GMP_USAGE) + find_package(GMP) +endif() + +if(GMP_FOUND) + set(SECP256K1_CONFIG_INC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/config_with_gmp") +else() + set(SECP256K1_CONFIG_INC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/config_without_gmp") + unset(GMP_INCLUDE_DIR CACHE) + unset(GMP_LIBRARIES CACHE) +endif() add_library(secp256k1 STATIC upstream/src/secp256k1.c @@ -13,7 +30,7 @@ target_include_directories(secp256k1 ${CMAKE_CURRENT_SOURCE_DIR}/upstream/include PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/upstream/src - ${CMAKE_CURRENT_SOURCE_DIR} + ${SECP256K1_CONFIG_INC_DIR} ${GMP_INCLUDE_DIR} ) diff --git a/secp256k1/libsecp256k1-config.h b/secp256k1/libsecp256k1-config.h deleted file mode 100644 index c1f4762c9..000000000 --- a/secp256k1/libsecp256k1-config.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -//optimizations that any compiler we target have -#define HAVE_BUILTIN_CLZLL 1 -#define HAVE_BUILTIN_EXPECT 1 -#define HAVE___INT128 1 - -//use GMP for bignum -#define HAVE_LIBGMP 1 -#define USE_NUM_GMP 1 -#define USE_FIELD_INV_NUM 1 -#define USE_SCALAR_INV_NUM 1 - -//use impls best for 64-bit -#define USE_FIELD_5X52 1 -#define USE_SCALAR_4X64 1 - -//enable asm -#ifdef __x86_64__ - #define USE_ASM_X86_64 1 -#endif diff --git a/src/crypto/elliptic_secp256k1.cpp b/src/crypto/elliptic_secp256k1.cpp index 47b55b790..826d57358 100644 --- a/src/crypto/elliptic_secp256k1.cpp +++ b/src/crypto/elliptic_secp256k1.cpp @@ -63,10 +63,11 @@ namespace fc { namespace ecc { } static const public_key_data empty_pub; - static const private_key_secret empty_priv; + fc::sha512 private_key::get_shared_secret( const public_key& other )const { + static const private_key_secret empty_priv; FC_ASSERT( my->_key != empty_priv ); FC_ASSERT( other.my->_key != empty_pub ); public_key_data pub(other.my->_key); diff --git a/src/crypto/private_key.cpp b/src/crypto/private_key.cpp index d67097122..2056897df 100644 --- a/src/crypto/private_key.cpp +++ b/src/crypto/private_key.cpp @@ -88,7 +88,7 @@ namespace fc { namespace crypto { return Data(fc::variant(key_bytes).as()); } - static private_key::storage_type parse_base58(const string& base58str) + static private_key::storage_type priv_parse_base58(const string& base58str) { const auto pivot = base58str.find('_'); @@ -108,7 +108,7 @@ namespace fc { namespace crypto { } private_key::private_key(const std::string& base58str) - :_storage(parse_base58(base58str)) + :_storage(priv_parse_base58(base58str)) {} std::string private_key::to_string(const fc::yield_function_t& yield) const diff --git a/src/crypto/signature.cpp b/src/crypto/signature.cpp index 1372679f1..44294fff3 100644 --- a/src/crypto/signature.cpp +++ b/src/crypto/signature.cpp @@ -16,7 +16,7 @@ namespace fc { namespace crypto { } }; - static signature::storage_type parse_base58(const std::string& base58str) + static signature::storage_type sig_parse_base58(const std::string& base58str) { try { constexpr auto prefix = config::signature_base_prefix; @@ -32,7 +32,7 @@ namespace fc { namespace crypto { } FC_RETHROW_EXCEPTIONS( warn, "error parsing signature", ("str", base58str ) ) } signature::signature(const std::string& base58str) - :_storage(parse_base58(base58str)) + :_storage(sig_parse_base58(base58str)) {} int signature::which() const { diff --git a/src/log/console_appender.cpp b/src/log/console_appender.cpp index a4aeb51df..784f77f03 100644 --- a/src/log/console_appender.cpp +++ b/src/log/console_appender.cpp @@ -20,7 +20,7 @@ namespace fc { public: config cfg; color::type lc[log_level::off+1]; - bool use_syslog_header{getenv("JOURNAL_STREAM")}; + bool use_syslog_header{getenv("JOURNAL_STREAM") != nullptr}; #ifdef WIN32 HANDLE console_handle; #endif From 6f94f76ec993e19b7218f7ad39b755bdb4482824 Mon Sep 17 00:00:00 2001 From: johndebord Date: Wed, 10 Jun 2020 17:53:03 +0000 Subject: [PATCH 002/124] Adding secp256k1 config --- .../config_with_gmp/libsecp256k1-config.h | 21 +++++++++++++++++++ .../config_without_gmp/libsecp256k1-config.h | 20 ++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 secp256k1/config_with_gmp/libsecp256k1-config.h create mode 100644 secp256k1/config_without_gmp/libsecp256k1-config.h diff --git a/secp256k1/config_with_gmp/libsecp256k1-config.h b/secp256k1/config_with_gmp/libsecp256k1-config.h new file mode 100644 index 000000000..c1f4762c9 --- /dev/null +++ b/secp256k1/config_with_gmp/libsecp256k1-config.h @@ -0,0 +1,21 @@ +#pragma once + +//optimizations that any compiler we target have +#define HAVE_BUILTIN_CLZLL 1 +#define HAVE_BUILTIN_EXPECT 1 +#define HAVE___INT128 1 + +//use GMP for bignum +#define HAVE_LIBGMP 1 +#define USE_NUM_GMP 1 +#define USE_FIELD_INV_NUM 1 +#define USE_SCALAR_INV_NUM 1 + +//use impls best for 64-bit +#define USE_FIELD_5X52 1 +#define USE_SCALAR_4X64 1 + +//enable asm +#ifdef __x86_64__ + #define USE_ASM_X86_64 1 +#endif diff --git a/secp256k1/config_without_gmp/libsecp256k1-config.h b/secp256k1/config_without_gmp/libsecp256k1-config.h new file mode 100644 index 000000000..24ed1c987 --- /dev/null +++ b/secp256k1/config_without_gmp/libsecp256k1-config.h @@ -0,0 +1,20 @@ +#pragma once + +//optimizations that any compiler we target have +#define HAVE_BUILTIN_CLZLL 1 +#define HAVE_BUILTIN_EXPECT 1 +#define HAVE___INT128 1 + +//use internal field & num impls +#define USE_FIELD_INV_BUILTIN 1 +#define USE_SCALAR_INV_BUILTIN 1 +#define USE_NUM_NONE 1 + +//use impls best for 64-bit +#define USE_FIELD_5X52 1 +#define USE_SCALAR_4X64 1 + +//enable asm +#ifdef __x86_64__ + #define USE_ASM_X86_64 1 +#endif From ffd81a82b049bc39d2c20763fc17f1d2c1708dca Mon Sep 17 00:00:00 2001 From: johndebord Date: Thu, 14 May 2020 18:41:41 -0400 Subject: [PATCH 003/124] Fix narrowing conversion error --- src/log/console_appender.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/log/console_appender.cpp b/src/log/console_appender.cpp index a4aeb51df..6d3236d40 100644 --- a/src/log/console_appender.cpp +++ b/src/log/console_appender.cpp @@ -20,7 +20,7 @@ namespace fc { public: config cfg; color::type lc[log_level::off+1]; - bool use_syslog_header{getenv("JOURNAL_STREAM")}; + bool use_syslog_header{static_cast(getenv("JOURNAL_STREAM"))}; #ifdef WIN32 HANDLE console_handle; #endif From bb1b5b112b65f171e435c82a40a3490939c88d9b Mon Sep 17 00:00:00 2001 From: johndebord Date: Thu, 14 May 2020 19:25:42 -0400 Subject: [PATCH 004/124] Change to equality check against `nullptr` --- src/log/console_appender.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/log/console_appender.cpp b/src/log/console_appender.cpp index 6d3236d40..025344b1e 100644 --- a/src/log/console_appender.cpp +++ b/src/log/console_appender.cpp @@ -20,7 +20,7 @@ namespace fc { public: config cfg; color::type lc[log_level::off+1]; - bool use_syslog_header{static_cast(getenv("JOURNAL_STREAM"))}; + bool use_syslog_header{getenv("JOURNAL_STREAM") != nullptr}; #ifdef WIN32 HANDLE console_handle; #endif From f5261b095bf9863a90a314ea7f8663e969602f44 Mon Sep 17 00:00:00 2001 From: Huang-Ming Huang Date: Fri, 8 May 2020 17:02:37 -0500 Subject: [PATCH 005/124] move binary_stream to become fc::datastream --- include/fc/io/bio_device_adaptor.hpp | 32 ++++++++++ include/fc/io/cfile.hpp | 31 ++++++++++ include/fc/io/datastream.hpp | 89 +++++++++++++++++++++++++++- 3 files changed, 149 insertions(+), 3 deletions(-) create mode 100644 include/fc/io/bio_device_adaptor.hpp diff --git a/include/fc/io/bio_device_adaptor.hpp b/include/fc/io/bio_device_adaptor.hpp new file mode 100644 index 000000000..609fe3671 --- /dev/null +++ b/include/fc/io/bio_device_adaptor.hpp @@ -0,0 +1,32 @@ +#pragma once + +#include +namespace fc { + +namespace bio = boost::iostreams; + +template +struct device_adaptor { + STREAM& strm; + + typedef char char_type; + typedef Category category; + size_t write(const char* data, size_t n) { return strm.write(data, n), n; } + size_t read(char* data, size_t n) { return strm.read(data, n), n; } +}; + +template +device_adaptor to_sink(STREAM& strm) { + return device_adaptor{strm}; +} + +template +device_adaptor to_source(STREAM& strm) { + return device_adaptor{strm}; +} + +template +device_adaptor to_seekable(STREAM& strm) { + return device_adaptor{strm}; +} +} // namespace fc \ No newline at end of file diff --git a/include/fc/io/cfile.hpp b/include/fc/io/cfile.hpp index 72adf331c..5d1705b98 100644 --- a/include/fc/io/cfile.hpp +++ b/include/fc/io/cfile.hpp @@ -1,6 +1,8 @@ #pragma once #include +#include #include +#include #ifndef _WIN32 #define FC_FOPEN(p, m) fopen(p, m) @@ -113,6 +115,17 @@ class cfile { } } + bool eof() const { return feof(_file.get()) != 0; } + + int getc() { + int ret = fgetc(_file.get()); + if (ret == EOF) { + throw std::ios_base::failure( "cfile: " + _file_path.generic_string() + + " unable to read 1 byte"); + } + return ret; + } + void close() { _file.reset(); _open = false; @@ -159,6 +172,24 @@ inline cfile_datastream cfile::create_datastream() { return cfile_datastream(*this); } +template <> +class datastream : public fc::cfile { + public: + using fc::cfile::cfile; + + bool seekp(size_t pos) { return this->seek(pos), true; } + + bool get(char& c) { + c = this->getc(); + return true; + } + + bool remaining() { return !this->eof(); } + + fc::cfile& storage() { return *this; } + const fc::cfile& storage() const { return *this; } +}; + } // namespace fc diff --git a/include/fc/io/datastream.hpp b/include/fc/io/datastream.hpp index 1ac171e1e..12d875cb5 100644 --- a/include/fc/io/datastream.hpp +++ b/include/fc/io/datastream.hpp @@ -1,7 +1,9 @@ #pragma once #include +#include #include #include +#include #include @@ -12,15 +14,18 @@ namespace detail NO_RETURN void throw_datastream_range_error( const char* file, size_t len, int64_t over ); } +template +class datastream; + /** - * The purpose of this datastream is to provide a fast, effecient, means + * The purpose of this datastream is to provide a fast, efficient, means * of calculating the amount of data "about to be written" and then * writing it. This means having two modes of operation, "test run" where * you call the entire pack sequence calculating the size, and then * actually packing it after doing a single allocation. */ template -class datastream { +class datastream || std::is_same_v>> { public: datastream( T start, size_t s ) :_start(start),_pos(start),_end(start+s){}; @@ -77,7 +82,7 @@ class datastream { }; template<> -class datastream { +class datastream { public: datastream( size_t init_size = 0):_size(init_size){}; inline bool skip( size_t s ) { _size += s; return true; } @@ -91,6 +96,84 @@ class datastream { size_t _size; }; +template +class datastream>> { + private: + Streambuf buf; + + public: + template + datastream(Args&&... args) + : buf(std::forward(args)...) {} + + size_t read(char* data, size_t n) { return buf.sgetn(data, n); } + size_t write(const char* data, size_t n) { return buf.sputn(data, n); } + size_t tellp() { return this->pubseekoff(0, std::ios::cur); } + bool get(char& c) { + c = buf.sbumpc(); + return true; + } + bool seekp(size_t off) { + buf.pubseekoff(off, std::ios::beg); + return true; + } + bool remaining() { return buf.in_avail(); } + + Streambuf& storage() { return buf; } + const Streambuf& storage() const { return buf; } +}; + +template +class datastream, Container> || + std::is_same_v, Container>)>> { + private: + Container _container; + size_t cur; + + public: + template + datastream(Args&&... args) + : _container(std::forward(args)...) + , cur(0) {} + + size_t read(char* s, size_t n) { + if (cur + n > _container.size()) { + FC_THROW_EXCEPTION(out_of_range_exception, + "read datastream> of length ${len} over by ${over}", + ("len", _container.size())("over", _container.size() - n)); + } + std::copy_n(_container.begin() + cur, n, s); + cur += n; + return n; + } + + size_t write(const char* s, size_t n) { + _container.resize(std::max(cur + n, _container.size())); + std::copy_n(s, n, _container.begin() + cur); + cur += n; + return n; + } + + bool seekp(size_t off) { + cur = off; + return true; + } + + size_t tellp() const { return cur; } + + bool get(char& c) { + this->read(&c, 1); + return true; + } + + size_t remaining() const { return _container.size() - cur; } + + Container& storage() { return _container; } + const Container& storage() const { return _container; } +}; + + + template inline datastream& operator<<(datastream& ds, const __int128& d) { ds.write( (const char*)&d, sizeof(d) ); From 3b910c8a5009f4eaa0a410f6f4cc988ccb58983a Mon Sep 17 00:00:00 2001 From: Huang-Ming Huang Date: Sun, 10 May 2020 11:54:17 -0500 Subject: [PATCH 006/124] add skip to datastream --- include/fc/io/cfile.hpp | 7 +++++++ include/fc/io/datastream.hpp | 2 ++ 2 files changed, 9 insertions(+) diff --git a/include/fc/io/cfile.hpp b/include/fc/io/cfile.hpp index 5d1705b98..ec62e0ca4 100644 --- a/include/fc/io/cfile.hpp +++ b/include/fc/io/cfile.hpp @@ -78,6 +78,13 @@ class cfile { } } + void skip( long loc) { + if( 0 != fseek( _file.get(), loc, SEEK_CUR ) ) { + throw std::ios_base::failure( "cfile: " + _file_path.generic_string() + + " unable to SEEK_CUR to: " + std::to_string(loc) ); + } + } + void read( char* d, size_t n ) { size_t result = fread( d, 1, n, _file.get() ); if( result != n ) { diff --git a/include/fc/io/datastream.hpp b/include/fc/io/datastream.hpp index 12d875cb5..0da6c98d4 100644 --- a/include/fc/io/datastream.hpp +++ b/include/fc/io/datastream.hpp @@ -109,6 +109,7 @@ class datastreampubseekoff(0, std::ios::cur); } + bool skip(size_t p) { this->pubseekoff(p, std::ios::cur); return true; } bool get(char& c) { c = buf.sbumpc(); return true; @@ -160,6 +161,7 @@ class datastreamread(&c, 1); From 4d881e6af896bbbeb21bfcc31972b147a1443550 Mon Sep 17 00:00:00 2001 From: Huang-Ming Huang Date: Thu, 21 May 2020 14:23:17 -0500 Subject: [PATCH 007/124] Add unity build support for some targets --- CMakeLists.txt | 5 +++++ src/crypto/elliptic_secp256k1.cpp | 3 ++- src/crypto/private_key.cpp | 6 +++--- src/crypto/signature.cpp | 4 ++-- 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b21fd6cea..93f06c7c2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -123,6 +123,11 @@ list(APPEND sources ${fc_headers}) setup_library( fc SOURCES ${sources} LIBRARY_TYPE STATIC DONT_INSTALL_LIBRARY ) +if(ENABLE_UNITY_BUILD) + set_target_properties(fc PROPERTIES UNITY_BUILD TRUE) +endif() + + function(detect_thread_name) include(CheckSymbolExists) list(APPEND CMAKE_REQUIRED_DEFINITIONS -D_GNU_SOURCE) diff --git a/src/crypto/elliptic_secp256k1.cpp b/src/crypto/elliptic_secp256k1.cpp index 47b55b790..826d57358 100644 --- a/src/crypto/elliptic_secp256k1.cpp +++ b/src/crypto/elliptic_secp256k1.cpp @@ -63,10 +63,11 @@ namespace fc { namespace ecc { } static const public_key_data empty_pub; - static const private_key_secret empty_priv; + fc::sha512 private_key::get_shared_secret( const public_key& other )const { + static const private_key_secret empty_priv; FC_ASSERT( my->_key != empty_priv ); FC_ASSERT( other.my->_key != empty_pub ); public_key_data pub(other.my->_key); diff --git a/src/crypto/private_key.cpp b/src/crypto/private_key.cpp index d67097122..a2a9f39fd 100644 --- a/src/crypto/private_key.cpp +++ b/src/crypto/private_key.cpp @@ -88,7 +88,7 @@ namespace fc { namespace crypto { return Data(fc::variant(key_bytes).as()); } - static private_key::storage_type parse_base58(const string& base58str) + static private_key::storage_type priv_parse_base58(const string& base58str) { const auto pivot = base58str.find('_'); @@ -108,7 +108,7 @@ namespace fc { namespace crypto { } private_key::private_key(const std::string& base58str) - :_storage(parse_base58(base58str)) + :_storage(priv_parse_base58(base58str)) {} std::string private_key::to_string(const fc::yield_function_t& yield) const @@ -118,7 +118,7 @@ namespace fc { namespace crypto { if (which == 0) { using default_type = storage_type::template type_at<0>; return to_wif(_storage.template get(), yield); - } + } auto data_str = _storage.visit(base58str_visitor(yield)); return std::string(config::private_key_base_prefix) + "_" + data_str; diff --git a/src/crypto/signature.cpp b/src/crypto/signature.cpp index 1372679f1..44294fff3 100644 --- a/src/crypto/signature.cpp +++ b/src/crypto/signature.cpp @@ -16,7 +16,7 @@ namespace fc { namespace crypto { } }; - static signature::storage_type parse_base58(const std::string& base58str) + static signature::storage_type sig_parse_base58(const std::string& base58str) { try { constexpr auto prefix = config::signature_base_prefix; @@ -32,7 +32,7 @@ namespace fc { namespace crypto { } FC_RETHROW_EXCEPTIONS( warn, "error parsing signature", ("str", base58str ) ) } signature::signature(const std::string& base58str) - :_storage(parse_base58(base58str)) + :_storage(sig_parse_base58(base58str)) {} int signature::which() const { From 5821b89b40973a9d3a71aae506609b8e6a9dbb6b Mon Sep 17 00:00:00 2001 From: Huang-Ming Huang Date: Mon, 1 Jun 2020 08:07:14 -0500 Subject: [PATCH 008/124] strip trailing spaces --- src/crypto/private_key.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/crypto/private_key.cpp b/src/crypto/private_key.cpp index a2a9f39fd..2056897df 100644 --- a/src/crypto/private_key.cpp +++ b/src/crypto/private_key.cpp @@ -118,7 +118,7 @@ namespace fc { namespace crypto { if (which == 0) { using default_type = storage_type::template type_at<0>; return to_wif(_storage.template get(), yield); - } + } auto data_str = _storage.visit(base58str_visitor(yield)); return std::string(config::private_key_base_prefix) + "_" + data_str; From 8bd78e4c1f6e60722d1554ea4548e07f4d5970b7 Mon Sep 17 00:00:00 2001 From: Huang-Ming Huang Date: Fri, 29 May 2020 11:23:38 -0500 Subject: [PATCH 009/124] Add support for block log splitting --- include/fc/filesystem.hpp | 1 + src/filesystem.cpp | 2 ++ 2 files changed, 3 insertions(+) diff --git a/include/fc/filesystem.hpp b/include/fc/filesystem.hpp index 7484f2a5a..e3bfc3fa1 100644 --- a/include/fc/filesystem.hpp +++ b/include/fc/filesystem.hpp @@ -81,6 +81,7 @@ namespace fc { bool is_relative()const; bool is_absolute()const; + bool empty() const; static char separator_char; diff --git a/src/filesystem.cpp b/src/filesystem.cpp index 2337d1017..24a96c99a 100644 --- a/src/filesystem.cpp +++ b/src/filesystem.cpp @@ -170,6 +170,8 @@ namespace fc { bool path::is_relative()const { return _p->is_relative(); } bool path::is_absolute()const { return _p->is_absolute(); } + bool path::empty() const { return _p->empty(); } + directory_iterator::directory_iterator( const fc::path& p ) :_p(p){} From 3a88ab5ffcccfaffabc19631be7a3a6024f781ca Mon Sep 17 00:00:00 2001 From: Huang-Ming Huang Date: Fri, 12 Jun 2020 09:22:17 -0500 Subject: [PATCH 010/124] Support unity build for unittests --- CMakeLists.txt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 93f06c7c2..320823ef8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -72,8 +72,7 @@ set( fc_sources src/log/log_message.cpp src/log/logger.cpp src/log/appender.cpp - src/log/console_appender.cpp - src/log/gelf_appender.cpp + src/log/console_appender.cpp src/log/dmlog_appender.cpp src/log/logger_config.cpp src/crypto/_digest_common.cpp @@ -111,6 +110,7 @@ set( fc_sources src/network/http/http_client.cpp src/compress/smaz.cpp src/compress/zlib.cpp + src/log/gelf_appender.cpp ) file( GLOB_RECURSE fc_headers ${CMAKE_CURRENT_SOURCE_DIR} *.hpp *.h ) @@ -125,6 +125,8 @@ setup_library( fc SOURCES ${sources} LIBRARY_TYPE STATIC DONT_INSTALL_LIBRARY ) if(ENABLE_UNITY_BUILD) set_target_properties(fc PROPERTIES UNITY_BUILD TRUE) + set_source_files_properties(src/io/json.cpp + PROPERTIES SKIP_UNITY_BUILD_INCLUSION TRUE) endif() From 5b0a3290dd2f86e512b97bf3de90c5f6df81d145 Mon Sep 17 00:00:00 2001 From: Huang-Ming Huang Date: Tue, 16 Jun 2020 11:33:38 -0500 Subject: [PATCH 011/124] consolidate unity build setting in one place --- CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 320823ef8..420f85352 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -124,7 +124,6 @@ list(APPEND sources ${fc_headers}) setup_library( fc SOURCES ${sources} LIBRARY_TYPE STATIC DONT_INSTALL_LIBRARY ) if(ENABLE_UNITY_BUILD) - set_target_properties(fc PROPERTIES UNITY_BUILD TRUE) set_source_files_properties(src/io/json.cpp PROPERTIES SKIP_UNITY_BUILD_INCLUSION TRUE) endif() From d11c258f9a13b9df05c363c173945970cdef9805 Mon Sep 17 00:00:00 2001 From: Huang-Ming Huang Date: Thu, 25 Jun 2020 17:07:36 -0500 Subject: [PATCH 012/124] const correctness fix --- include/fc/crypto/sha1.hpp | 3 ++- include/fc/crypto/sha224.hpp | 3 ++- include/fc/crypto/sha256.hpp | 5 +++-- include/fc/crypto/sha512.hpp | 3 ++- src/crypto/sha1.cpp | 3 ++- src/crypto/sha224.cpp | 4 ++-- src/crypto/sha256.cpp | 3 ++- src/crypto/sha512.cpp | 3 ++- 8 files changed, 17 insertions(+), 10 deletions(-) diff --git a/include/fc/crypto/sha1.hpp b/include/fc/crypto/sha1.hpp index 32fc2e49c..d8938f27a 100644 --- a/include/fc/crypto/sha1.hpp +++ b/include/fc/crypto/sha1.hpp @@ -13,7 +13,8 @@ class sha1 string str()const; operator string()const; - char* data()const; + char* data(); + const char* data()const; size_t data_size()const { return 20; } static sha1 hash( const char* d, uint32_t dlen ); diff --git a/include/fc/crypto/sha224.hpp b/include/fc/crypto/sha224.hpp index a6212082f..749fabc1d 100644 --- a/include/fc/crypto/sha224.hpp +++ b/include/fc/crypto/sha224.hpp @@ -16,7 +16,8 @@ class sha224 string str()const; operator string()const; - char* data()const; + char* data(); + const char* data()const; size_t data_size()const { return 224 / 8; } static sha224 hash( const char* d, uint32_t dlen ); diff --git a/include/fc/crypto/sha256.hpp b/include/fc/crypto/sha256.hpp index bef0fea68..591a2fa38 100644 --- a/include/fc/crypto/sha256.hpp +++ b/include/fc/crypto/sha256.hpp @@ -17,8 +17,9 @@ class sha256 string str()const; operator string()const; - char* data()const; - size_t data_size()const { return 256 / 8; } + const char* data()const; + char* data(); + size_t data_size() const { return 256 / 8; } static sha256 hash( const char* d, uint32_t dlen ); static sha256 hash( const string& ); diff --git a/include/fc/crypto/sha512.hpp b/include/fc/crypto/sha512.hpp index ef10887c5..c2d7f96d8 100644 --- a/include/fc/crypto/sha512.hpp +++ b/include/fc/crypto/sha512.hpp @@ -14,7 +14,8 @@ class sha512 string str()const; operator string()const; - char* data()const; + char* data(); + const char* data()const; size_t data_size()const { return 512 / 8; } static sha512 hash( const char* d, uint32_t dlen ); diff --git a/src/crypto/sha1.cpp b/src/crypto/sha1.cpp index 29c98a1e2..c9f15abf3 100644 --- a/src/crypto/sha1.cpp +++ b/src/crypto/sha1.cpp @@ -22,7 +22,8 @@ string sha1::str()const { } sha1::operator string()const { return str(); } -char* sha1::data()const { return (char*)&_hash[0]; } +char* sha1::data() { return (char*)&_hash[0]; } +const char* sha1::data()const { return (char*)&_hash[0]; } struct sha1::encoder::impl { diff --git a/src/crypto/sha224.cpp b/src/crypto/sha224.cpp index ac00dbbf1..6cac4a1ed 100644 --- a/src/crypto/sha224.cpp +++ b/src/crypto/sha224.cpp @@ -21,8 +21,8 @@ namespace fc { } sha224::operator string()const { return str(); } - char* sha224::data()const { return (char*)&_hash[0]; } - + char* sha224::data() { return (char*)&_hash[0]; } + const char* sha224::data() const { return (const char*)&_hash[0]; } struct sha224::encoder::impl { SHA256_CTX ctx; diff --git a/src/crypto/sha256.cpp b/src/crypto/sha256.cpp index 807384b00..567697270 100644 --- a/src/crypto/sha256.cpp +++ b/src/crypto/sha256.cpp @@ -28,7 +28,8 @@ namespace fc { } sha256::operator string()const { return str(); } - char* sha256::data()const { return (char*)&_hash[0]; } + const char* sha256::data()const { return (const char*)&_hash[0]; } + char* sha256::data() { return (char*)&_hash[0]; } struct sha256::encoder::impl { diff --git a/src/crypto/sha512.cpp b/src/crypto/sha512.cpp index ec4e116cd..35b35ef8d 100644 --- a/src/crypto/sha512.cpp +++ b/src/crypto/sha512.cpp @@ -21,7 +21,8 @@ namespace fc { } sha512::operator string()const { return str(); } - char* sha512::data()const { return (char*)&_hash[0]; } + char* sha512::data() { return (char*)&_hash[0]; } + const char* sha512::data()const { return (const char*)&_hash[0]; } struct sha512::encoder::impl { From 015ab6b9653c47e327de7618332788aec35a0b5f Mon Sep 17 00:00:00 2001 From: Jeffrey Smith II Date: Wed, 5 Aug 2020 14:45:04 -0400 Subject: [PATCH 013/124] FC Consolidated Security Fixes for develop - Escape Unicode C1 control code points. Co-Authored-By: Kevin Heifner heifnerk@objectcomputing.com --- include/fc/io/json.hpp | 21 ++--- include/fc/utf8.hpp | 11 ++- src/io/json.cpp | 176 ++++++++++++++++-------------------- src/utf8.cpp | 57 +++++++++--- src/variant.cpp | 29 ++++-- test/io/test_json.cpp | 198 +++-------------------------------------- 6 files changed, 174 insertions(+), 318 deletions(-) diff --git a/include/fc/io/json.hpp b/include/fc/io/json.hpp index 686e8a518..cdae756c5 100644 --- a/include/fc/io/json.hpp +++ b/include/fc/io/json.hpp @@ -31,15 +31,9 @@ namespace fc stringify_large_ints_and_doubles = 0, legacy_generator = 1 }; - using yield_function_t = fc::optional_delegate; + using yield_function_t = fc::optional_delegate; static constexpr uint64_t max_length_limit = std::numeric_limits::max(); - static constexpr size_t escape_string_yeild_check_count = 128; - static ostream& to_stream( ostream& out, const fc::string&, const yield_function_t& yield ); - static ostream& to_stream( ostream& out, const variant& v, const yield_function_t& yield, const output_formatting format = output_formatting::stringify_large_ints_and_doubles ); - static ostream& to_stream( ostream& out, const variants& v, const yield_function_t& yield, const output_formatting format = output_formatting::stringify_large_ints_and_doubles ); - static ostream& to_stream( ostream& out, const variant_object& v, const yield_function_t& yield, const output_formatting format = output_formatting::stringify_large_ints_and_doubles ); - static ostream& to_stream( ostream& out, const variant& v, const fc::time_point& deadline, const output_formatting format = output_formatting::stringify_large_ints_and_doubles, const uint64_t max_len = max_length_limit ); - + static constexpr size_t escape_string_yield_check_count = 128; static variant from_string( const string& utf8_str, const parse_type ptype = parse_type::legacy_parser, uint32_t max_depth = DEFAULT_MAX_RECURSION_DEPTH ); static variants variants_from_string( const string& utf8_str, const parse_type ptype = parse_type::legacy_parser, uint32_t max_depth = DEFAULT_MAX_RECURSION_DEPTH ); static string to_string( const variant& v, const yield_function_t& yield, const output_formatting format = output_formatting::stringify_large_ints_and_doubles); @@ -65,9 +59,9 @@ namespace fc template static string to_string( const T& v, const fc::time_point& deadline, const output_formatting format = output_formatting::stringify_large_ints_and_doubles, const uint64_t max_len = max_length_limit ) { - const auto yield = [&](std::ostream& os) { + const auto yield = [&](size_t s) { FC_CHECK_DEADLINE(deadline); - FC_ASSERT(os.tellp() <= max_len); + FC_ASSERT(s <= max_len); }; return to_string( variant(v), yield, format ); } @@ -75,9 +69,9 @@ namespace fc template static string to_pretty_string( const T& v, const fc::time_point& deadline = fc::time_point::maximum(), const output_formatting format = output_formatting::stringify_large_ints_and_doubles, const uint64_t max_len = max_length_limit ) { - const auto yield = [&](std::ostream& os) { + const auto yield = [&](size_t s) { FC_CHECK_DEADLINE(deadline); - FC_ASSERT( os.tellp() <= max_len ); + FC_ASSERT( s <= max_len ); }; return to_pretty_string( variant(v), yield, format ); } @@ -89,7 +83,8 @@ namespace fc } }; - void escape_string( const string& str, std::ostream& os, const json::yield_function_t& yield ); + std::string escape_string( const std::string_view& str, const json::yield_function_t& yield, bool escape_control_chars = true ); + } // fc #undef DEFAULT_MAX_RECURSION_DEPTH diff --git a/include/fc/utf8.hpp b/include/fc/utf8.hpp index c5730295d..84468690c 100644 --- a/include/fc/utf8.hpp +++ b/include/fc/utf8.hpp @@ -8,7 +8,16 @@ namespace fc { - std::string prune_invalid_utf8( const std::string& str ); + /** + * 0x80-0x9F C1 control characters are considered invalid as well as invalid utf8 code points. + * @return true if prune_invalid_utf8 should be called. + */ + bool is_valid_utf8( const std::string_view& str ); + + /** + * Invalid utf8 code points are purned, 0x80-0x9F C1 control characters are escaped + */ + std::string prune_invalid_utf8( const std::string_view& str ); bool is_utf8( const std::string& str ); diff --git a/src/io/json.cpp b/src/io/json.cpp index 93102345d..01d57b084 100644 --- a/src/io/json.cpp +++ b/src/io/json.cpp @@ -3,6 +3,7 @@ //#include #include //#include +#include #include #include #include @@ -485,91 +486,96 @@ namespace fc */ /** - * Convert '\t', '\a', '\n', '\\' and '"' to "\t\a\n\\\"" - * - * All other characters are printed as UTF8. + * Convert '\t', '\r', '\n', '\\' and '"' to "\t\r\n\\\"" if escape_control_chars == true + * Convert all other < 32 & 127 ascii to escaped unicode "\u00xx" + * Removes invalid utf8 characters + * Escapes Control sequence Introducer 0x9b to \u009b + * All other characters unmolested. */ - void escape_string( const string& str, std::ostream& os, const json::yield_function_t& yield ) + std::string escape_string( const std::string_view& str, const json::yield_function_t& yield, bool escape_control_chars ) { - os << '"'; + string r; + const auto init_size = str.size(); + r.reserve( init_size + 13 ); // allow for a few escapes size_t i = 0; for( auto itr = str.begin(); itr != str.end(); ++i,++itr ) { - if( i % json::escape_string_yeild_check_count == 0 ) yield(os); + if( i % json::escape_string_yield_check_count == 0 ) yield( init_size + r.size() ); switch( *itr ) { - case '\b': // \x08 - os << "\\b"; - break; - case '\f': // \x0c - os << "\\f"; - break; + case '\x00': r += "\\u0000"; break; + case '\x01': r += "\\u0001"; break; + case '\x02': r += "\\u0002"; break; + case '\x03': r += "\\u0003"; break; + case '\x04': r += "\\u0004"; break; + case '\x05': r += "\\u0005"; break; + case '\x06': r += "\\u0006"; break; + case '\x07': r += "\\u0007"; break; // \a is not valid JSON + case '\x08': r += "\\u0008"; break; // \b + // case '\x09': r += "\\u0009"; break; // \t + // case '\x0a': r += "\\u000a"; break; // \n + case '\x0b': r += "\\u000b"; break; + case '\x0c': r += "\\u000c"; break; // \f + // case '\x0d': r += "\\u000d"; break; // \r + case '\x0e': r += "\\u000e"; break; + case '\x0f': r += "\\u000f"; break; + case '\x10': r += "\\u0010"; break; + case '\x11': r += "\\u0011"; break; + case '\x12': r += "\\u0012"; break; + case '\x13': r += "\\u0013"; break; + case '\x14': r += "\\u0014"; break; + case '\x15': r += "\\u0015"; break; + case '\x16': r += "\\u0016"; break; + case '\x17': r += "\\u0017"; break; + case '\x18': r += "\\u0018"; break; + case '\x19': r += "\\u0019"; break; + case '\x1a': r += "\\u001a"; break; + case '\x1b': r += "\\u001b"; break; + case '\x1c': r += "\\u001c"; break; + case '\x1d': r += "\\u001d"; break; + case '\x1e': r += "\\u001e"; break; + case '\x1f': r += "\\u001f"; break; + + case '\x7f': r += "\\u007f"; break; + + // if escape_control_chars=true these fall-through to default + case '\t': // \x09 + if( escape_control_chars ) { + r += "\\t"; + break; + } case '\n': // \x0a - os << "\\n"; - break; + if( escape_control_chars ) { + r += "\\n"; + break; + } case '\r': // \x0d - os << "\\r"; - break; - case '\t': // \x09 - os << "\\t"; - break; + if( escape_control_chars ) { + r += "\\r"; + break; + } case '\\': - os << "\\\\"; - break; + if( escape_control_chars ) { + r += "\\\\"; + break; + } case '\"': - os << "\\\""; - break; - case '\x00': os << "\\u0000"; break; - case '\x01': os << "\\u0001"; break; - case '\x02': os << "\\u0002"; break; - case '\x03': os << "\\u0003"; break; - case '\x04': os << "\\u0004"; break; - case '\x05': os << "\\u0005"; break; - case '\x06': os << "\\u0006"; break; - case '\x07': os << "\\u0007"; break; // \a is not valid JSON - // case '\x08': os << "\\u0008"; break; // \b - // case '\x09': os << "\\u0009"; break; // \t - // case '\x0a': os << "\\u000a"; break; // \n - case '\x0b': os << "\\u000b"; break; - // case '\x0c': os << "\\u000c"; break; // \f - // case '\x0d': os << "\\u000d"; break; // \r - case '\x0e': os << "\\u000e"; break; - case '\x0f': os << "\\u000f"; break; - - case '\x10': os << "\\u0010"; break; - case '\x11': os << "\\u0011"; break; - case '\x12': os << "\\u0012"; break; - case '\x13': os << "\\u0013"; break; - case '\x14': os << "\\u0014"; break; - case '\x15': os << "\\u0015"; break; - case '\x16': os << "\\u0016"; break; - case '\x17': os << "\\u0017"; break; - case '\x18': os << "\\u0018"; break; - case '\x19': os << "\\u0019"; break; - case '\x1a': os << "\\u001a"; break; - case '\x1b': os << "\\u001b"; break; - case '\x1c': os << "\\u001c"; break; - case '\x1d': os << "\\u001d"; break; - case '\x1e': os << "\\u001e"; break; - case '\x1f': os << "\\u001f"; break; - + if( escape_control_chars ) { + r += "\\\""; + break; + } default: - os << *itr; - //toUTF8( *itr, os ); + r += *itr; } } - os << '"'; - } - std::ostream& json::to_stream( std::ostream& out, const std::string& str, const json::yield_function_t& yield ) - { - escape_string( str, out, yield ); - return out; + + return is_valid_utf8( r ) ? r : prune_invalid_utf8( r ); } template void to_stream( T& os, const variants& a, const json::yield_function_t& yield, const json::output_formatting format ) { - yield(os); + yield(os.tellp()); os << '['; auto itr = a.begin(); @@ -586,13 +592,13 @@ namespace fc template void to_stream( T& os, const variant_object& o, const json::yield_function_t& yield, const json::output_formatting format ) { - yield(os); + yield(os.tellp()); os << '{'; auto itr = o.begin(); while( itr != o.end() ) { - escape_string( itr->key(), os, yield ); + os << '"' << escape_string( itr->key(), yield ) << '"'; os << ':'; to_stream( os, itr->value(), yield, format ); ++itr; @@ -605,7 +611,7 @@ namespace fc template void to_stream( T& os, const variant& v, const json::yield_function_t& yield, const json::output_formatting format ) { - yield(os); + yield(os.tellp()); switch( v.get_type() ) { case variant::null_type: @@ -643,10 +649,10 @@ namespace fc os << v.as_string(); return; case variant::string_type: - escape_string( v.get_string(), os, yield ); + os << '"' << escape_string( v.get_string(), yield ) << '"'; return; case variant::blob_type: - escape_string( v.as_string(), os, yield ); + os << '"' << escape_string( v.as_string(), yield ) << '"'; return; case variant::array_type: { @@ -669,7 +675,7 @@ namespace fc { std::stringstream ss; fc::to_stream( ss, v, yield, format ); - yield(ss); + yield(ss.tellp()); return ss.str(); } @@ -781,7 +787,7 @@ namespace fc return o.good(); } else { std::ofstream o(fi.generic_string().c_str()); - const auto yield = [&](std::ostream& os) { + const auto yield = [&](size_t s) { // no limitation }; fc::to_stream( o, v, yield, format ); @@ -827,30 +833,6 @@ namespace fc } */ - std::ostream& json::to_stream( std::ostream& out, const variant& v, const json::yield_function_t& yield, const json::output_formatting format ) - { - fc::to_stream( out, v, yield, format ); - return out; - } - std::ostream& json::to_stream( std::ostream& out, const variants& v, const json::yield_function_t& yield, const json::output_formatting format ) - { - fc::to_stream( out, v, yield, format ); - return out; - } - std::ostream& json::to_stream( std::ostream& out, const variant_object& v, const json::yield_function_t& yield, const json::output_formatting format ) - { - fc::to_stream( out, v, yield, format ); - return out; - } - - std::ostream& json::to_stream( std::ostream& out, const variant& v, const fc::time_point& deadline, const json::output_formatting format, const uint64_t max_len ) { - const auto yield = [&](std::ostream& os) { - FC_CHECK_DEADLINE(deadline); - FC_ASSERT( os.tellp() <= max_len ); - }; - return to_stream(out, v, yield, format); - } - bool json::is_valid( const std::string& utf8_str, const json::parse_type ptype, const uint32_t max_depth ) { if( utf8_str.size() == 0 ) return false; diff --git a/src/utf8.cpp b/src/utf8.cpp index 811de8c25..b274e3eaf 100644 --- a/src/utf8.cpp +++ b/src/utf8.cpp @@ -2,33 +2,68 @@ #include "utf8/checked.h" #include "utf8/core.h" -#include "utf8/unchecked.h" -#include -#include #include #include -#include namespace fc { - bool is_utf8( const std::string& str ) + inline constexpr char hex_digits[] = "0123456789abcdef"; + + bool is_utf8( const std::string& str ) + { + return utf8::is_valid( str.begin(), str.end() ); + } + + // tweaked utf8::find_invalid that also considers provided range as invalid + // @param invalid_range, indicates additional invalid values + // @return [iterator to found invalid char, the value found if in range of provided pair invalid_range otherwise UINT32_MAX] + template + std::pair find_invalid(octet_iterator start, octet_iterator end, + const std::pair& invalid_range) { - return utf8::is_valid( str.begin(), str.end() ); + FC_ASSERT( invalid_range.first <= invalid_range.second ); + octet_iterator result = start; + uint32_t value = UINT32_MAX; + while( result != end ) { + octet_iterator itr = result; + utf8::internal::utf_error err_code = utf8::internal::validate_next( result, end, value ); + if( err_code != utf8::internal::UTF8_OK ) + return {result, UINT32_MAX}; + if( value >= invalid_range.first && value <= invalid_range.second ) + return {itr, value}; + } + return {result, UINT32_MAX}; } - string prune_invalid_utf8( const string& str ) { - string result; - auto itr = utf8::find_invalid(str.begin(), str.end()); - if( itr == str.end() ) return str; + bool is_valid_utf8( const std::string_view& str ) { + const auto invalid_range = std::make_pair(0x80, 0x9F); + auto [itr, v] = find_invalid( str.begin(), str.end(), invalid_range ); + return itr == str.end(); + } + + // escape 0x80-0x9F C1 control characters + string prune_invalid_utf8( const std::string_view& str ) { + const auto invalid_range = std::make_pair(0x80, 0x9F); + auto [itr, v] = find_invalid( str.begin(), str.end(), invalid_range ); + if( itr == str.end() ) return std::string( str ); + + string result; + auto escape = [&result](uint32_t v) { // v is [0x80-0x9F] + result += "\\u00"; + result += hex_digits[v >> 4u]; + result += hex_digits[v & 15u]; + }; result = string( str.begin(), itr ); + if( v != UINT32_MAX ) escape(v); while( itr != str.end() ) { ++itr; auto start = itr; - itr = utf8::find_invalid( start, str.end()); + std::tie(itr, v) = find_invalid( start, str.end(), invalid_range ); result += string( start, itr ); + if( v != UINT32_MAX ) escape(v); } return result; } diff --git a/src/variant.cpp b/src/variant.cpp index b13f28725..bea6f5c61 100644 --- a/src/variant.cpp +++ b/src/variant.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include namespace fc @@ -730,6 +731,14 @@ void from_variant( const variant& v, UInt<64>& n ) { n = v.as_uint64(); } constexpr size_t minimize_max_size = 1024; +// same behavior as std::string::substr only removes invalid utf8, and lower ascii +void clean_append( string& app, const std::string_view& s, size_t pos = 0, size_t len = string::npos ) { + std::string_view sub = s.substr( pos, len ); + app.reserve( app.size() + sub.size() ); + const bool escape_control_chars = false; + app += escape_string( sub, nullptr, escape_control_chars ); +} + string format_string( const string& frmt, const variant_object& args, bool minimize ) { std::string result; @@ -746,9 +755,9 @@ string format_string( const string& frmt, const variant_object& args, bool minim size_t next = format.find( '$' ); while( prev != string::npos && prev < format.size() ) { if( next != string::npos ) { - result += format.substr( prev, next - prev ); + clean_append( result, format, prev, next - prev ); } else { - result += format.substr( prev ); + clean_append( result, format, prev ); } // if we got to the end, return it. @@ -779,7 +788,9 @@ string format_string( const string& frmt, const variant_object& args, bool minim } else { const auto max_length = minimize ? minimize_sub_max_size : std::numeric_limits::max(); try { - result += json::to_string(val->value(), fc::time_point::maximum(), json::output_formatting::stringify_large_ints_and_doubles, max_length); + // clean_append not needed as to_string is valid utf8 + result += json::to_string( val->value(), fc::time_point::maximum(), + json::output_formatting::stringify_large_ints_and_doubles, max_length ); } catch (...) { replaced = false; } @@ -788,25 +799,25 @@ string format_string( const string& frmt, const variant_object& args, bool minim if( minimize && val->value().get_blob().data.size() > minimize_sub_max_size ) { replaced = false; } else { - result += val->value().as_string(); + clean_append( result, val->value().as_string() ); } } else if( val->value().is_string() ) { if( minimize && val->value().get_string().size() > minimize_sub_max_size ) { auto sz = std::min( minimize_sub_max_size, minimize_max_size - result.size() ); - result += val->value().get_string().substr( 0, sz ); + clean_append( result, val->value().get_string(), 0, sz ); result += "..."; } else { - result += val->value().get_string(); + clean_append( result, val->value().get_string() ); } } else { - result += val->value().as_string(); + clean_append( result, val->value().as_string() ); } } else { replaced = false; } if( !replaced ) { result += "${"; - result += key; + clean_append( result, key ); result += "}"; } prev = next + 1; @@ -816,7 +827,7 @@ string format_string( const string& frmt, const variant_object& args, bool minim // we didn't find it.. continue to while... } } else { - result += format[prev]; + clean_append( result, format, prev, 1 ); ++prev; next = format.find( '$', prev ); } diff --git a/test/io/test_json.cpp b/test/io/test_json.cpp index 6552a0e79..a07fbefad 100644 --- a/test/io/test_json.cpp +++ b/test/io/test_json.cpp @@ -11,21 +11,21 @@ BOOST_AUTO_TEST_SUITE(json_test_suite) namespace json_test_util { constexpr size_t exception_limit_size = 250; - const json::yield_function_t yield_deadline_exception_at_start = [](std::ostream& os) { + const json::yield_function_t yield_deadline_exception_at_start = [](size_t s) { FC_CHECK_DEADLINE(fc::time_point::now() - fc::milliseconds(1)); }; - const json::yield_function_t yield_deadline_exception_in_mid = [](std::ostream& os) { - if (os.tellp() >= exception_limit_size) { + const json::yield_function_t yield_deadline_exception_in_mid = [](size_t s) { + if (s >= exception_limit_size) { throw fc::timeout_exception(fc::exception_code::timeout_exception_code, "timeout_exception", "execution timed out" ); } }; - const json::yield_function_t yield_length_exception = [](std::ostream& os) { - FC_ASSERT( os.tellp() <= exception_limit_size ); + const json::yield_function_t yield_length_exception = [](size_t s) { + FC_ASSERT( s <= exception_limit_size ); }; - const json::yield_function_t yield_no_limitation = [](std::ostream& os) { + const json::yield_function_t yield_no_limitation = [](size_t s) { // no limitation }; @@ -42,176 +42,8 @@ namespace json_test_util { const string escape_input_str = "\\b\\f\\n\\r\\t-\\-\\\\-\\x0\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\x09\\x0a\\x0b\\x0c\\x0d\\x0e\\x0f" \ "\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f-" + repeat_chars; - const auto multiple_num = [](const size_t num, const size_t base) -> size_t { - return (num / base + ((num % base == 0) ? 0 : 1)) * base; - }; - } // namespace json_test_util -BOOST_AUTO_TEST_CASE(to_stream_test) -{ - { - // to_stream( ostream& out, const fc::string&, const yield_function_t& yield ); - std::stringstream escape_out_str_ss; - fc::escape_string(json_test_util::escape_input_str, escape_out_str_ss, json_test_util::yield_no_limitation); - const auto size_different = escape_out_str_ss.str().size() - json_test_util::escape_input_str.size(); - const auto expected_out_str_size = json_test_util::multiple_num(json_test_util::exception_limit_size, json::escape_string_yeild_check_count) + size_different - 1; - BOOST_CHECK_LT(json_test_util::repeat_char_num, json_test_util::escape_input_str.size()); - BOOST_CHECK_LT(json_test_util::escape_input_str.size() - json_test_util::repeat_char_num, json_test_util::exception_limit_size); // by using size_different to calculate expected string - { - std::stringstream deadline_exception_at_start_ss; - BOOST_CHECK_EXCEPTION(json::to_stream( deadline_exception_at_start_ss, json_test_util::escape_input_str, json_test_util::yield_deadline_exception_at_start), - fc::timeout_exception, - json_test_util::time_except_verf_func); - BOOST_CHECK_EQUAL(deadline_exception_at_start_ss.str(), "\""); - } - { - std::stringstream deadline_exception_in_mid_ss; - BOOST_CHECK_EXCEPTION(json::to_stream( deadline_exception_in_mid_ss, json_test_util::escape_input_str, json_test_util::yield_deadline_exception_in_mid), - fc::timeout_exception, - json_test_util::time_except_verf_func); - BOOST_CHECK_EQUAL(deadline_exception_in_mid_ss.str(), escape_out_str_ss.str().substr(0, expected_out_str_size)); - } - { - std::stringstream length_except_mid_ss; - BOOST_CHECK_EXCEPTION(json::to_stream(length_except_mid_ss, json_test_util::escape_input_str, json_test_util::yield_length_exception), - fc::assert_exception, - json_test_util::length_limit_except_verf_func); - BOOST_CHECK_EQUAL(length_except_mid_ss.str(), escape_out_str_ss.str().substr(0, expected_out_str_size)); - } - } - { - // to_stream( ostream& out, const variant& v, const fc::time_point& deadline, const uint64_t max_len = max_length_limit, output_formatting format = stringify_large_ints_and_doubles ); - { - variant v(json_test_util::escape_input_str); - std::stringstream deadline_exception_at_start_ss; - BOOST_CHECK_EXCEPTION(json::to_stream( deadline_exception_at_start_ss, v, fc::time_point::min(), json::output_formatting::stringify_large_ints_and_doubles, json::max_length_limit), - fc::timeout_exception, - json_test_util::time_except_verf_func); - BOOST_CHECK_EQUAL(deadline_exception_at_start_ss.str().empty(), true); - } - { - constexpr size_t max_len = 10; - variant v(json_test_util::repeat_chars); - std::stringstream length_exception_in_mid_ss; - BOOST_CHECK_EXCEPTION(json::to_stream( length_exception_in_mid_ss, v, fc::time_point::maximum(), json::output_formatting::stringify_large_ints_and_doubles, max_len), - fc::assert_exception, - json_test_util::length_limit_except_verf_func); - BOOST_CHECK_EQUAL(length_exception_in_mid_ss.str(), - "\"" + json_test_util::repeat_chars.substr(0, json_test_util::multiple_num(max_len, json::escape_string_yeild_check_count))); - } - { - variant v(json_test_util::repeat_chars); - std::stringstream length_exception_in_mid_ss; - BOOST_CHECK_NO_THROW(json::to_stream( length_exception_in_mid_ss, v, fc::time_point::maximum(), json::output_formatting::stringify_large_ints_and_doubles, json::max_length_limit)); - BOOST_CHECK_EQUAL(length_exception_in_mid_ss.str(), "\"" + json_test_util::repeat_chars + "\""); - } - } - { - // to_stream( ostream& out, const variant& v, const yield_function_t& yield, output_formatting format = stringify_large_ints_and_doubles ); - const variant v(json_test_util::repeat_chars); - BOOST_CHECK_LT(json_test_util::exception_limit_size, json_test_util::repeat_chars.size()); - { - std::stringstream deadline_exception_at_start_ss; - BOOST_CHECK_EXCEPTION(json::to_stream( deadline_exception_at_start_ss, v, json_test_util::yield_deadline_exception_at_start), - fc::timeout_exception, - json_test_util::time_except_verf_func); - BOOST_CHECK_EQUAL(deadline_exception_at_start_ss.str().empty(), true); - } - { - std::stringstream deadline_exception_in_mid_ss; - BOOST_CHECK_EXCEPTION(json::to_stream( deadline_exception_in_mid_ss, v, json_test_util::yield_deadline_exception_in_mid), - fc::timeout_exception, - json_test_util::time_except_verf_func); - BOOST_CHECK_EQUAL(deadline_exception_in_mid_ss.str(), - "\"" + json_test_util::repeat_chars.substr(0, json_test_util::multiple_num(json_test_util::exception_limit_size, json::escape_string_yeild_check_count))); - } - { - std::stringstream length_exception_in_mid_ss; - BOOST_CHECK_EXCEPTION(json::to_stream( length_exception_in_mid_ss, v, json_test_util::yield_length_exception), - fc::assert_exception, - json_test_util::length_limit_except_verf_func); - BOOST_CHECK_EQUAL(length_exception_in_mid_ss.str(), - "\"" + json_test_util::repeat_chars.substr(0, json_test_util::multiple_num(json_test_util::exception_limit_size, json::escape_string_yeild_check_count))); - } - { - std::stringstream no_exception_ss; - BOOST_CHECK_NO_THROW(json::to_stream( no_exception_ss, v, json_test_util::yield_no_limitation)); - BOOST_CHECK_EQUAL(no_exception_ss.str(), "\"" + json_test_util::repeat_chars + "\""); - } - } - { - // to_stream( ostream& out, const variants& v, const yield_function_t& yield, output_formatting format = stringify_large_ints_and_doubles ); - const std::string a_list(json_test_util::repeat_char_num, 'a'); - const std::string b_list(json_test_util::repeat_char_num, 'b'); - const variants variant_list{variant(a_list), variant(b_list)}; - BOOST_CHECK_LT(json_test_util::exception_limit_size, a_list.size() + b_list.size()); - { - std::stringstream deadline_exception_at_start_ss; - BOOST_CHECK_EXCEPTION(json::to_stream( deadline_exception_at_start_ss, variant_list, json_test_util::yield_deadline_exception_at_start), - fc::timeout_exception, - json_test_util::time_except_verf_func); - BOOST_CHECK_EQUAL(deadline_exception_at_start_ss.str().empty(), true); - } - { - std::stringstream deadline_exception_in_mid_ss; - BOOST_CHECK_EXCEPTION(json::to_stream( deadline_exception_in_mid_ss, variant_list, json_test_util::yield_deadline_exception_in_mid), - fc::timeout_exception, - json_test_util::time_except_verf_func); - BOOST_CHECK_EQUAL(deadline_exception_in_mid_ss.str(), - "[\"" + a_list.substr(0, json_test_util::multiple_num(json_test_util::exception_limit_size, json::escape_string_yeild_check_count))); - } - { - std::stringstream length_exception_in_mid_ss; - BOOST_CHECK_EXCEPTION(json::to_stream( length_exception_in_mid_ss, variant_list, json_test_util::yield_length_exception), - fc::assert_exception, - json_test_util::length_limit_except_verf_func); - BOOST_CHECK_EQUAL(length_exception_in_mid_ss.str(), - "[\"" + a_list.substr(0, json_test_util::multiple_num(json_test_util::exception_limit_size, json::escape_string_yeild_check_count))); - } - { - std::stringstream no_exception_ss; - BOOST_CHECK_NO_THROW(json::to_stream( no_exception_ss, variant_list, json_test_util::yield_no_limitation)); - BOOST_CHECK_EQUAL(no_exception_ss.str(), "[\"" + a_list + "\",\"" + b_list + "\"]"); - } - } - { - // to_stream( ostream& out, const variant_object& v, const yield_function_t& yield, output_formatting format = stringify_large_ints_and_doubles ); - const std::string a_list(json_test_util::repeat_char_num, 'a'); - const std::string b_list(json_test_util::repeat_char_num, 'b'); - const variant_object vo(mutable_variant_object()("a", a_list)("b", b_list)); - BOOST_CHECK_LT(json_test_util::exception_limit_size, a_list.size() + b_list.size()); - { - std::stringstream deadline_exception_at_start_ss; - BOOST_CHECK_EXCEPTION(json::to_stream( deadline_exception_at_start_ss, vo, json_test_util::yield_deadline_exception_at_start), - fc::timeout_exception, - json_test_util::time_except_verf_func); - BOOST_CHECK_EQUAL(deadline_exception_at_start_ss.str().empty(), true); - } - { - std::stringstream deadline_exception_in_mid_ss; - BOOST_CHECK_EXCEPTION(json::to_stream( deadline_exception_in_mid_ss, vo, json_test_util::yield_deadline_exception_in_mid), - fc::timeout_exception, - json_test_util::time_except_verf_func); - BOOST_CHECK_EQUAL(deadline_exception_in_mid_ss.str(), - "{\"a\":\"" + a_list.substr(0, json_test_util::multiple_num(json_test_util::exception_limit_size, json::escape_string_yeild_check_count))); - } - { - std::stringstream length_exception_in_mid_ss; - BOOST_CHECK_EXCEPTION(json::to_stream( length_exception_in_mid_ss, vo, json_test_util::yield_length_exception), - fc::assert_exception, - json_test_util::length_limit_except_verf_func); - BOOST_CHECK_EQUAL(length_exception_in_mid_ss.str(), - "{\"a\":\"" + a_list.substr(0, json_test_util::multiple_num(json_test_util::exception_limit_size, json::escape_string_yeild_check_count))); - } - { - std::stringstream no_exception_ss; - BOOST_CHECK_NO_THROW(json::to_stream( no_exception_ss, vo, json_test_util::yield_no_limitation)); - BOOST_CHECK_EQUAL(no_exception_ss.str(), "{\"a\":\"" + a_list + "\",\"b\":\"" + b_list + "\"}"); - } - } -} - BOOST_AUTO_TEST_CASE(to_string_test) { { // to_string( const variant& v, const fc::time_point& deadline, const uint64_t max_len = max_length_limit, output_formatting format = stringify_large_ints_and_doubles); @@ -366,35 +198,27 @@ BOOST_AUTO_TEST_CASE(to_pretty_string_test) BOOST_AUTO_TEST_CASE(escape_string_test) { - std::stringstream escape_out_str_ss; - fc::escape_string(json_test_util::escape_input_str, escape_out_str_ss, json_test_util::yield_no_limitation); - const auto size_different = escape_out_str_ss.str().size() - json_test_util::escape_input_str.size(); - const auto expected_out_str_size = json_test_util::multiple_num(json_test_util::exception_limit_size, json::escape_string_yeild_check_count) + size_different - 1; + std::string escape_out_str; + escape_out_str = fc::escape_string(json_test_util::escape_input_str, json_test_util::yield_no_limitation); BOOST_CHECK_LT(json_test_util::repeat_char_num, json_test_util::escape_input_str.size()); BOOST_CHECK_LT(json_test_util::escape_input_str.size() - json_test_util::repeat_char_num, json_test_util::exception_limit_size); // by using size_different to calculate expected string { // simulate exceed time exception at the beginning of processing - std::stringstream escape_time_except_begin_ss; - BOOST_CHECK_EXCEPTION(escape_string(json_test_util::escape_input_str, escape_time_except_begin_ss, json_test_util::yield_deadline_exception_at_start), + BOOST_CHECK_EXCEPTION(escape_string(json_test_util::escape_input_str, json_test_util::yield_deadline_exception_at_start), fc::timeout_exception, json_test_util::time_except_verf_func); - BOOST_CHECK_EQUAL(escape_time_except_begin_ss.str(), "\""); } { // simulate exceed time exception in the middle of processing - std::stringstream escape_time_except_mid_ss; - BOOST_CHECK_EXCEPTION(escape_string(json_test_util::escape_input_str, escape_time_except_mid_ss, json_test_util::yield_deadline_exception_in_mid), + BOOST_CHECK_EXCEPTION(escape_string(json_test_util::escape_input_str, json_test_util::yield_deadline_exception_in_mid), fc::timeout_exception, json_test_util::time_except_verf_func); - BOOST_CHECK_EQUAL(escape_time_except_mid_ss.str(), escape_out_str_ss.str().substr(0, expected_out_str_size)); } { // length limitation exception in the middle of processing - std::stringstream length_except_mid_ss; - BOOST_CHECK_EXCEPTION(escape_string(json_test_util::escape_input_str, length_except_mid_ss, json_test_util::yield_length_exception), + BOOST_CHECK_EXCEPTION(escape_string(json_test_util::escape_input_str, json_test_util::yield_length_exception), fc::assert_exception, json_test_util::length_limit_except_verf_func); - BOOST_CHECK_EQUAL(length_except_mid_ss.str(), escape_out_str_ss.str().substr(0, expected_out_str_size)); } } From 0a6c072a2054a9c90c743e3d0df4d26a034ff976 Mon Sep 17 00:00:00 2001 From: Matt Witherspoon <32485495+spoonincode@users.noreply.github.com> Date: Mon, 10 Aug 2020 11:30:56 -0400 Subject: [PATCH 014/124] add std::list<> support to fc pack/unpack --- include/fc/io/raw.hpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/include/fc/io/raw.hpp b/include/fc/io/raw.hpp index 00bd74985..35aecc161 100644 --- a/include/fc/io/raw.hpp +++ b/include/fc/io/raw.hpp @@ -583,6 +583,26 @@ namespace fc { } } + template + inline void pack( Stream& s, const std::list& value ) { + FC_ASSERT( value.size() <= MAX_NUM_ARRAY_ELEMENTS ); + fc::raw::pack( s, unsigned_int((uint32_t)value.size()) ); + for( const auto& i : value ) { + fc::raw::pack( s, i ); + } + } + + template + inline void unpack( Stream& s, std::list& value ) { + unsigned_int size; fc::raw::unpack( s, size ); + FC_ASSERT( size.value <= MAX_NUM_ARRAY_ELEMENTS ); + while( size.value-- ) { + T i; + fc::raw::unpack( s, i ); + value.emplace_back( std::move( i ) ); + } + } + template inline void pack( Stream& s, const std::set& value ) { FC_ASSERT( value.size() <= MAX_NUM_ARRAY_ELEMENTS ); From 13feb7c4f7505c01b7f77954977b14f51035d51e Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Tue, 11 Aug 2020 16:37:02 -0500 Subject: [PATCH 015/124] Remove fc::uint128_t typedef to avoid confusion with eosio::chain::config::uint128_t typedef --- include/fc/uint128.hpp | 6 ++---- src/uint128.cpp | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/include/fc/uint128.hpp b/include/fc/uint128.hpp index c12ad0bd0..4663ccc4f 100644 --- a/include/fc/uint128.hpp +++ b/include/fc/uint128.hpp @@ -122,9 +122,7 @@ namespace fc uint64_t lo; }; static_assert( sizeof(uint128) == 2*sizeof(uint64_t), "validate packing assumptions" ); - - typedef uint128 uint128_t; - + class variant; void to_variant( const uint128& var, variant& vo ); @@ -155,7 +153,7 @@ namespace std }; } -FC_REFLECT( fc::uint128_t, (hi)(lo) ) +FC_REFLECT( fc::uint128, (hi)(lo) ) #ifdef _MSC_VER #pragma warning (pop) diff --git a/src/uint128.cpp b/src/uint128.cpp index c5b26a1eb..523569d78 100644 --- a/src/uint128.cpp +++ b/src/uint128.cpp @@ -331,7 +331,7 @@ namespace fc uint64_t y[4]; // final result y[0] = sl; - uint128_t acc = sh; + uint128 acc = sh; acc += ql; acc += rl; y[1] = acc.lo; From 7b5843e347121674ac730e0640cbe278d5370c92 Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Tue, 11 Aug 2020 16:52:21 -0500 Subject: [PATCH 016/124] Remove using namespace boost::multiprecision to avoid pulling in boost::multiprecision::uint128_t --- include/fc/io/raw.hpp | 7 ++++--- include/fc/variant.hpp | 7 ++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/include/fc/io/raw.hpp b/include/fc/io/raw.hpp index 35aecc161..b861bb4ce 100644 --- a/include/fc/io/raw.hpp +++ b/include/fc/io/raw.hpp @@ -27,11 +27,12 @@ namespace fc { namespace bip = boost::interprocess; using shared_string = bip::basic_string< char, std::char_traits< char >, bip::allocator >; - using namespace boost::multiprecision; template - using UInt = number >; + using UInt = boost::multiprecision::number< + boost::multiprecision::cpp_int_backend >; template - using Int = number >; + using Int = boost::multiprecision::number< + boost::multiprecision::cpp_int_backend >; template void pack( Stream& s, const UInt<256>& n ); template void unpack( Stream& s, UInt<256>& n ); template void pack( Stream& s, const Int<256>& n ); diff --git a/include/fc/variant.hpp b/include/fc/variant.hpp index 2dca7ef12..a9f98a749 100644 --- a/include/fc/variant.hpp +++ b/include/fc/variant.hpp @@ -53,11 +53,12 @@ namespace fc template void to_variant( const boost::multi_index_container& s, variant& v ); template void from_variant( const variant& v, boost::multi_index_container& s ); - using namespace boost::multiprecision; template - using UInt = number >; + using UInt = boost::multiprecision::number< + boost::multiprecision::cpp_int_backend >; template - using Int = number >; + using Int = boost::multiprecision::number< + boost::multiprecision::cpp_int_backend >; void to_variant( const UInt<8>& n, variant& v ); void from_variant( const variant& v, UInt<8>& n ); From 71a8cfdfa2291913e33d92d75b1086b41c0270a7 Mon Sep 17 00:00:00 2001 From: Timothy Banks Date: Tue, 16 Jun 2020 15:25:23 -0400 Subject: [PATCH 017/124] Stop using fc::optional. Start using std::optional --- include/fc/exception/exception.hpp | 3 +-- include/fc/filesystem.hpp | 7 +++---- include/fc/io/raw.hpp | 9 ++++----- include/fc/io/raw_fwd.hpp | 4 ++-- include/fc/log/logger_config.hpp | 2 +- include/fc/network/url.hpp | 11 +++++------ include/fc/reflect/typename.hpp | 3 +-- include/fc/reflect/variant.hpp | 4 ++-- include/fc/rpc/api_connection.hpp | 5 ++--- include/fc/rpc/binary_api_connection.hpp | 5 ++--- include/fc/string.hpp | 6 +++--- include/fc/time.hpp | 3 +-- include/fc/variant.hpp | 11 +++++------ src/filesystem.cpp | 6 +++--- src/log/gelf_appender.cpp | 6 +++--- src/log/logger_config.cpp | 4 ++-- src/network/gntp.cpp | 16 ++++++++-------- src/network/http/http_client.cpp | 16 ++++++++-------- src/network/ntp.cpp | 4 ++-- src/network/url.cpp | 20 ++++++++++---------- src/rpc/websocket_api.cpp | 2 +- 21 files changed, 69 insertions(+), 78 deletions(-) diff --git a/include/fc/exception/exception.hpp b/include/fc/exception/exception.hpp index 83ebb338e..c8565ccdd 100644 --- a/include/fc/exception/exception.hpp +++ b/include/fc/exception/exception.hpp @@ -4,7 +4,6 @@ * @brief Defines exception's used by fc */ #include -#include #include #include #include @@ -139,7 +138,7 @@ namespace fc void from_variant( const variant& e, exception& ll ); typedef std::shared_ptr exception_ptr; - typedef optional oexception; + typedef std::optional oexception; /** diff --git a/include/fc/filesystem.hpp b/include/fc/filesystem.hpp index e3bfc3fa1..389c61082 100644 --- a/include/fc/filesystem.hpp +++ b/include/fc/filesystem.hpp @@ -4,7 +4,6 @@ #include #include -#include #include namespace boost { @@ -195,13 +194,13 @@ namespace fc { { public: inline ~temp_file_base() { remove(); } - inline operator bool() const { return _path.valid(); } - inline bool operator!() const { return !_path; } + inline operator bool() const { return _path.has_value(); } + inline bool operator!() const { return !_path.has_value(); } const fc::path& path() const; void remove(); void release(); protected: - typedef fc::optional path_t; + typedef std::optional path_t; inline temp_file_base(const path_t& path) : _path(path) {} inline temp_file_base(path_t&& path) : _path(std::move(path)) {} path_t _path; diff --git a/include/fc/io/raw.hpp b/include/fc/io/raw.hpp index b861bb4ce..834e720d1 100644 --- a/include/fc/io/raw.hpp +++ b/include/fc/io/raw.hpp @@ -3,7 +3,6 @@ #include #include #include -#include #include #include #include @@ -268,13 +267,13 @@ namespace fc { // optional template - void pack( Stream& s, const fc::optional& v ) { - fc::raw::pack( s, bool(!!v) ); - if( !!v ) fc::raw::pack( s, *v ); + void pack( Stream& s, const std::optional& v ) { + fc::raw::pack( s, v.has_value() ); + if( v.has_value() ) fc::raw::pack( s, *v ); } template - void unpack( Stream& s, fc::optional& v ) + void unpack( Stream& s, std::optional& v ) { try { bool b; fc::raw::unpack( s, b ); if( b ) { v = T(); fc::raw::unpack( s, *v ); } diff --git a/include/fc/io/raw_fwd.hpp b/include/fc/io/raw_fwd.hpp index cb334cc67..e71d26ec3 100644 --- a/include/fc/io/raw_fwd.hpp +++ b/include/fc/io/raw_fwd.hpp @@ -83,9 +83,9 @@ namespace fc { template inline void unpack( Stream& s, ip::endpoint& v ); - template void unpack( Stream& s, fc::optional& v ); + template void unpack( Stream& s, std::optional& v ); template void unpack( Stream& s, const T& v ); - template void pack( Stream& s, const fc::optional& v ); + template void pack( Stream& s, const std::optional& v ); template void pack( Stream& s, const safe& v ); template void unpack( Stream& s, fc::safe& v ); diff --git a/include/fc/log/logger_config.hpp b/include/fc/log/logger_config.hpp index ffcb2f978..8d021cdc5 100644 --- a/include/fc/log/logger_config.hpp +++ b/include/fc/log/logger_config.hpp @@ -28,7 +28,7 @@ namespace fc { string name; ostring parent; /// if not set, then parents level is used. - fc::optional level; + std::optional level; bool enabled; /// if any appenders are sepecified, then parent's appenders are not set. bool additivity; diff --git a/include/fc/network/url.hpp b/include/fc/network/url.hpp index 09007073e..217f4e611 100644 --- a/include/fc/network/url.hpp +++ b/include/fc/network/url.hpp @@ -1,6 +1,5 @@ #pragma once #include -#include #include #include #include @@ -8,9 +7,9 @@ namespace fc { - typedef fc::optional ostring; - typedef fc::optional opath; - typedef fc::optional ovariant_object; + typedef std::optional ostring; + typedef std::optional opath; + typedef std::optional ovariant_object; namespace detail { class url_impl; } @@ -28,7 +27,7 @@ namespace fc { url( const url& c ); url( url&& c ); url( const string& proto, const ostring& host, const ostring& user, const ostring& pass, - const opath& path, const ostring& query, const ovariant_object& args, const fc::optional& port); + const opath& path, const ostring& query, const ovariant_object& args, const std::optional& port); ~url(); url& operator=( const url& c ); @@ -49,7 +48,7 @@ namespace fc { opath path()const; ostring query()const; ovariant_object args()const; - fc::optional port()const; + std::optional port()const; private: friend class mutable_url; diff --git a/include/fc/reflect/typename.hpp b/include/fc/reflect/typename.hpp index d96cfd9b2..889c8fefa 100644 --- a/include/fc/reflect/typename.hpp +++ b/include/fc/reflect/typename.hpp @@ -5,7 +5,6 @@ #include #include -#include #include #include @@ -58,7 +57,7 @@ namespace fc { return n.c_str(); } }; - template struct get_typename> + template struct get_typename> { static const char* name() { static std::string n = std::string("optional<") + get_typename::name() + ">"; diff --git a/include/fc/reflect/variant.hpp b/include/fc/reflect/variant.hpp index f26f73cbe..c3089b4cb 100644 --- a/include/fc/reflect/variant.hpp +++ b/include/fc/reflect/variant.hpp @@ -25,9 +25,9 @@ namespace fc private: template - void add( mutable_variant_object& vo, const char* name, const optional& v )const + void add( mutable_variant_object& vo, const char* name, const std::optional& v )const { - if( v.valid() ) + if( v.has_value() ) vo(name,*v); } template diff --git a/include/fc/rpc/api_connection.hpp b/include/fc/rpc/api_connection.hpp index c2268ea72..8cd6c94fa 100644 --- a/include/fc/rpc/api_connection.hpp +++ b/include/fc/rpc/api_connection.hpp @@ -1,6 +1,5 @@ #pragma once #include -#include #include #include #include @@ -174,7 +173,7 @@ namespace fc { std::function to_generic( const std::function(Args...)>& f )const; template - std::function to_generic( const std::function>(Args...)>& f )const; + std::function to_generic( const std::function>(Args...)>& f )const; template std::function to_generic( const std::function& f )const; @@ -393,7 +392,7 @@ namespace fc { } template std::function generic_api::api_visitor::to_generic( - const std::function>(Args...)>& f )const + const std::function>(Args...)>& f )const { auto api_con = _api_con; auto gapi = &_api; diff --git a/include/fc/rpc/binary_api_connection.hpp b/include/fc/rpc/binary_api_connection.hpp index 9c9ce2f7d..81a81d332 100644 --- a/include/fc/rpc/binary_api_connection.hpp +++ b/include/fc/rpc/binary_api_connection.hpp @@ -1,7 +1,6 @@ #pragma once #include #include -#include #include #include #include @@ -178,7 +177,7 @@ namespace fc { std::function to_generic( const std::function(Args...)>& f )const; template - std::function to_generic( const std::function>(Args...)>& f )const; + std::function to_generic( const std::function>(Args...)>& f )const; template std::function to_generic( const std::function& f )const; @@ -401,7 +400,7 @@ namespace fc { } template std::function generic_api::api_visitor::to_generic( - const std::function>(Args...)>& f )const + const std::function>(Args...)>& f )const { auto api_con = _api_con; auto gapi = &api; diff --git a/include/fc/string.hpp b/include/fc/string.hpp index 3a9323514..74dcf690b 100644 --- a/include/fc/string.hpp +++ b/include/fc/string.hpp @@ -1,9 +1,9 @@ #pragma once #include #include -#include #ifndef USE_FC_STRING +#include #include namespace fc { @@ -23,7 +23,7 @@ namespace fc inline fc::string to_string( size_t s) { return to_string(uint64_t(s)); } #endif - typedef fc::optional ostring; + typedef std::optional ostring; class variant_object; fc::string format_string( const fc::string&, const variant_object&, bool minimize = false ); fc::string trim( const fc::string& ); @@ -143,7 +143,7 @@ namespace fc { fc::string to_string( uint64_t ); fc::string to_string( int64_t ); - typedef fc::optional ostring; + typedef std::optional ostring; class variant_object; fc::string format_string( const fc::string&, const variant_object& ); diff --git a/include/fc/time.hpp b/include/fc/time.hpp index a401476e4..1c1b433bd 100644 --- a/include/fc/time.hpp +++ b/include/fc/time.hpp @@ -1,7 +1,6 @@ #pragma once #include #include -#include #ifdef _MSC_VER #pragma warning (push) @@ -121,7 +120,7 @@ namespace fc { uint32_t utc_seconds; }; - typedef fc::optional otime_point; + typedef std::optional otime_point; /** return a human-readable approximate time, relative to now() * e.g., "4 hours ago", "2 months ago", etc. diff --git a/include/fc/variant.hpp b/include/fc/variant.hpp index a9f98a749..9c372e3c8 100644 --- a/include/fc/variant.hpp +++ b/include/fc/variant.hpp @@ -10,7 +10,6 @@ #include // memset -#include #include #include #include @@ -349,10 +348,10 @@ namespace fc } template - variant( const optional& v ) + variant( const std::optional& v ) { memset( this, 0, sizeof(*this) ); - if( v.valid() ) *this = variant(*v); + if( v.has_value() ) *this = variant(*v); } template @@ -367,7 +366,7 @@ namespace fc double _data; ///< Alligned according to double requirements char _type[sizeof(void*)]; ///< pad to void* size }; - typedef optional ovariant; + typedef std::optional ovariant; /** @ingroup Serializable */ void from_variant( const variant& var, string& vo ); @@ -390,9 +389,9 @@ namespace fc void from_variant( const variant& var, uint32_t& vo ); /** @ingroup Serializable */ template - void from_variant( const variant& var, optional& vo ) + void from_variant( const variant& var, std::optional& vo ) { - if( var.is_null() ) vo = optional(); + if( var.is_null() ) vo = std::optional(); else { vo = T(); diff --git a/src/filesystem.cpp b/src/filesystem.cpp index 24a96c99a..a32cbae20 100644 --- a/src/filesystem.cpp +++ b/src/filesystem.cpp @@ -421,7 +421,7 @@ namespace fc { const fc::path& temp_file_base::path() const { - if (!_path) + if (!_path.has_value()) { FC_THROW( "Temporary directory has been released." ); } @@ -430,7 +430,7 @@ namespace fc { void temp_file_base::remove() { - if (_path.valid()) + if (_path.has_value()) { try { @@ -446,7 +446,7 @@ namespace fc { void temp_file_base::release() { - _path = fc::optional(); + _path = std::optional(); } const fc::path& home_path() diff --git a/src/log/gelf_appender.cpp b/src/log/gelf_appender.cpp index b5b3fc643..74e2e4b44 100644 --- a/src/log/gelf_appender.cpp +++ b/src/log/gelf_appender.cpp @@ -30,7 +30,7 @@ namespace fc { public: config cfg; - optional gelf_endpoint; + std::optional gelf_endpoint; udp_socket gelf_socket; impl(const config& c) : @@ -60,7 +60,7 @@ namespace fc catch (...) { } - if (!my->gelf_endpoint) + if (!my->gelf_endpoint.has_value()) { // couldn't parse as a numeric ip address, try resolving as a DNS name. // This can yield, so don't do it in the catch block above @@ -100,7 +100,7 @@ namespace fc void gelf_appender::log(const log_message& message) { - if (!my->gelf_endpoint) + if (!my->gelf_endpoint.has_value()) return; log_context context = message.get_context(); diff --git a/src/log/logger_config.cpp b/src/log/logger_config.cpp index 032b29c26..4d2ef776a 100644 --- a/src/log/logger_config.cpp +++ b/src/log/logger_config.cpp @@ -81,11 +81,11 @@ namespace fc { auto lgr = log_config::get().logger_map[cfg.loggers[i].name]; // TODO: finish configure logger here... - if( cfg.loggers[i].parent.valid() ) { + if( cfg.loggers[i].parent.has_value() ) { lgr.set_parent( log_config::get().logger_map[*cfg.loggers[i].parent] ); } lgr.set_name(cfg.loggers[i].name); - if( cfg.loggers[i].level.valid() ) lgr.set_log_level( *cfg.loggers[i].level ); + if( cfg.loggers[i].level.has_value() ) lgr.set_log_level( *cfg.loggers[i].level ); for( auto a = cfg.loggers[i].appenders.begin(); a != cfg.loggers[i].appenders.end(); ++a ){ diff --git a/src/network/gntp.cpp b/src/network/gntp.cpp index 89c17354f..0c522d313 100644 --- a/src/network/gntp.cpp +++ b/src/network/gntp.cpp @@ -45,19 +45,19 @@ namespace fc class gntp_notifier_impl { public: - gntp_notifier_impl(const std::string& host_to_notify = "127.0.0.1", uint16_t port = 23053, const optional& password = optional()); + gntp_notifier_impl(const std::string& host_to_notify = "127.0.0.1", uint16_t port = 23053, const std::optional& password = std::optional()); // there's no API to change these right now, it will always notify localhost at the default GNTP port std::string hostname; uint16_t port; - optional password; + std::optional password; std::string application_name; gntp_icon_ptr application_icon; gntp_notification_type_list notification_types; // list of all notification types we're registered to send - optional endpoint; // cache the last endpoint we've connected to + std::optional endpoint; // cache the last endpoint we've connected to bool connection_failed; // true after we've tried to connect and failed bool is_registered; // true after we've registered @@ -66,7 +66,7 @@ namespace fc }; gntp_notifier_impl::gntp_notifier_impl(const std::string& host_to_notify /* = "127.0.0.1" */, uint16_t port /* = 23053 */, - const optional& password /* = optional() */) : + const std::optional& password /* = std::optional() */) : hostname(host_to_notify), port(port), password(password), @@ -94,14 +94,14 @@ namespace fc ("error_report", er.to_detail_string())); sock->close(); // clear the cached endpoint and fall through to the full connection procedure - endpoint = optional(); + endpoint = std::optional(); } catch (...) { ilog("Failed to connect to GNTP service using an endpoint that previously worked"); sock->close(); // clear the cached endpoint and fall through to the full connection procedure - endpoint = optional(); + endpoint = std::optional(); } } if (!connected) @@ -165,7 +165,7 @@ namespace fc } gntp_notifier::gntp_notifier(const std::string& host_to_notify /* = "127.0.0.1" */, uint16_t port /* = 23053 */, - const optional& password /* = optional() */) : + const std::optional& password /* = std::optional() */) : my(new detail::gntp_notifier_impl(host_to_notify, port, password)) { } @@ -243,7 +243,7 @@ namespace fc } } gntp_guid gntp_notifier::send_notification(std::string name, std::string title, std::string text, - const gntp_icon_ptr& icon, optional coalescingId /* = optional() */) + const gntp_icon_ptr& icon, std::optional coalescingId /* = std::optional() */) { if (my->connection_failed) return gntp_guid(); diff --git a/src/network/http/http_client.cpp b/src/network/http/http_client.cpp index a943b9cc0..cf1e07a04 100644 --- a/src/network/http/http_client.cpp +++ b/src/network/http/http_client.cpp @@ -85,7 +85,7 @@ class http_client_impl { } }); - optional f_result; + std::optional f_result; f(f_result); _ioc.restart(); @@ -118,7 +118,7 @@ class http_client_impl { tcp::resolver local_resolver(_ioc); bool cancelled = false; - auto res = sync_do_with_deadline(s, deadline, [&local_resolver, &cancelled, &s, &host, &port](optional& final_ec){ + auto res = sync_do_with_deadline(s, deadline, [&local_resolver, &cancelled, &s, &host, &port](std::optional& final_ec){ local_resolver.async_resolve(host, port, [&cancelled, &s, &final_ec](const error_code& ec, tcp::resolver::results_type resolved ){ if (ec) { final_ec.emplace(ec); @@ -141,7 +141,7 @@ class http_client_impl { template error_code sync_write_with_timeout(SyncReadStream& s, http::request& req, const deadline_type& deadline ) { - return sync_do_with_deadline(s, deadline, [&s, &req](optional& final_ec){ + return sync_do_with_deadline(s, deadline, [&s, &req](std::optional& final_ec){ http::async_write(s, req, [&final_ec]( const error_code& ec, std::size_t ) { final_ec.emplace(ec); }); @@ -150,7 +150,7 @@ class http_client_impl { template error_code sync_read_with_timeout(SyncReadStream& s, boost::beast::flat_buffer& buffer, http::response& res, const deadline_type& deadline ) { - return sync_do_with_deadline(s, deadline, [&s, &buffer, &res](optional& final_ec){ + return sync_do_with_deadline(s, deadline, [&s, &buffer, &res](std::optional& final_ec){ http::async_read(s, buffer, res, [&final_ec]( const error_code& ec, std::size_t ) { final_ec.emplace(ec); }); @@ -158,7 +158,7 @@ class http_client_impl { } host_key url_to_host_key( const url& dest ) { - FC_ASSERT(dest.host(), "Provided URL has no host"); + FC_ASSERT(dest.host().has_value(), "Provided URL has no host"); uint16_t port = 80; if (dest.port()) { port = *dest.port(); @@ -213,7 +213,7 @@ class http_client_impl { error_code ec = sync_connect_with_timeout(ssl_socket->next_layer(), *dest.host(), dest.port() ? std::to_string(*dest.port()) : "443", deadline); if (!ec) { - ec = sync_do_with_deadline(ssl_socket->next_layer(), deadline, [&ssl_socket](optional& final_ec) { + ec = sync_do_with_deadline(ssl_socket->next_layer(), deadline, [&ssl_socket](std::optional& final_ec) { ssl_socket->async_handshake(ssl::stream_base::client, [&final_ec](const error_code& ec) { final_ec.emplace(ec); }); @@ -316,7 +316,7 @@ class http_client_impl { variant post_sync(const url& dest, const variant& payload, const fc::time_point& _deadline) { static const deadline_type epoch(boost::gregorian::date(1970, 1, 1)); auto deadline = epoch + boost::posix_time::microseconds(_deadline.time_since_epoch().count()); - FC_ASSERT(dest.host(), "No host set on URL"); + FC_ASSERT(dest.host().has_value(), "No host set on URL"); string path = dest.path() ? dest.path()->generic_string() : "/"; if (dest.query()) { @@ -426,7 +426,7 @@ class http_client_impl { if(socket_file.empty()) FC_THROW_EXCEPTION( parse_error_exception, "couldn't discover socket path"); url_path = "/" / url_path; - return _unix_url_paths.emplace(full_url, fc::url("unix", socket_file.string(), ostring(), ostring(), url_path.string(), ostring(), ovariant_object(), fc::optional())).first->second; + return _unix_url_paths.emplace(full_url, fc::url("unix", socket_file.string(), ostring(), ostring(), url_path.string(), ostring(), ovariant_object(), std::optional())).first->second; } #endif diff --git a/src/network/ntp.cpp b/src/network/ntp.cpp index 539407195..00aeadf87 100644 --- a/src/network/ntp.cpp +++ b/src/network/ntp.cpp @@ -243,11 +243,11 @@ namespace fc my->_ntp_thread.async( [=](){ my->request_now(); } ).get(); } - optional ntp::get_time()const + std::optional ntp::get_time()const { if( my->_last_ntp_delta_initialized ) return fc::time_point::now() + fc::microseconds(my->_last_ntp_delta_microseconds); - return optional(); + return std::optional(); } } //namespace fc diff --git a/src/network/url.cpp b/src/network/url.cpp index 069f94f7a..29c247974 100644 --- a/src/network/url.cpp +++ b/src/network/url.cpp @@ -60,7 +60,7 @@ namespace fc _path = fc::path( "/" ) / _lpath; #endif std::getline( ss, _largs ); - if( _args.valid() && _args->size() ) + if( _args.has_value() && _args->size() ) { // TODO: args = fc::move(_args); _query = fc::move(_largs); @@ -74,7 +74,7 @@ namespace fc opath _path; ostring _query; ovariant_object _args; - fc::optional _port; + std::optional _port; }; } @@ -91,17 +91,17 @@ namespace fc { std::stringstream ss; ss<_proto<<"://"; - if( my->_user.valid() ) { + if( my->_user.has_value() ) { ss << *my->_user; - if( my->_pass.valid() ) { + if( my->_pass.has_value() ) { ss<<":"<<*my->_pass; } ss<<"@"; } - if( my->_host.valid() ) ss<<*my->_host; - if( my->_port.valid() ) ss<<":"<<*my->_port; - if( my->_path.valid() ) ss<_path->generic_string(); - if( my->_query.valid() ) ss<<"?"<<*my->_query; + if( my->_host.has_value() ) ss<<*my->_host; + if( my->_port.has_value() ) ss<<":"<<*my->_port; + if( my->_path.has_value() ) ss<_path->generic_string(); + if( my->_query.has_value() ) ss<<"?"<<*my->_query; // if( my->_args ) ss<<"?"<<*my->_args; return ss.str(); } @@ -132,7 +132,7 @@ namespace fc } url::url( const string& proto, const ostring& host, const ostring& user, const ostring& pass, - const opath& path, const ostring& query, const ovariant_object& args, const fc::optional& port) + const opath& path, const ostring& query, const ovariant_object& args, const std::optional& port) :my( std::make_shared() ) { my->_proto = proto; @@ -191,7 +191,7 @@ namespace fc { return my->_args; } - fc::optional url::port()const + std::optional url::port()const { return my->_port; } diff --git a/src/rpc/websocket_api.cpp b/src/rpc/websocket_api.cpp index 60ef7062b..8539fc7cf 100644 --- a/src/rpc/websocket_api.cpp +++ b/src/rpc/websocket_api.cpp @@ -77,7 +77,7 @@ void websocket_api_connection::send_notice( uint64_t callback_id, variants args /* = variants() */ ) { - fc::rpc::request req{ optional(), "notice", {callback_id, std::move(args)}}; + fc::rpc::request req{ std::optional(), "notice", {callback_id, std::move(args)}}; _connection.send_message( fc::json::to_string(req) ); } From 4d6e9dd0323987406a67b051de183c66fb977878 Mon Sep 17 00:00:00 2001 From: Timothy Banks Date: Tue, 16 Jun 2020 15:31:17 -0400 Subject: [PATCH 018/124] Remove fc/optional.hpp --- include/fc/optional.hpp | 276 ---------------------------------------- 1 file changed, 276 deletions(-) delete mode 100644 include/fc/optional.hpp diff --git a/include/fc/optional.hpp b/include/fc/optional.hpp deleted file mode 100644 index 520bbde41..000000000 --- a/include/fc/optional.hpp +++ /dev/null @@ -1,276 +0,0 @@ -#pragma once -#include -#include - - -namespace fc { -#ifdef _MSC_VER -# pragma warning(push) -# pragma warning(disable:4521) /* multiple copy ctors */ -# pragma warning(disable:4522) /* multiple assignment operators */ -#endif - bool assert_optional(bool is_valid ); // defined in exception.cpp - - /** - * @brief provides stack-based nullable value similar to boost::optional - * - * Simply including boost::optional adds 35,000 lines to each object file, using - * fc::optional adds less than 400. - */ - template - class optional - { - public: - typedef T value_type; - typedef typename std::aligned_storage::type storage_type; - - optional():_valid(false){} - ~optional(){ reset(); } - - optional( optional& o ) - :_valid(false) - { - if( o._valid ) new (ptr()) T( *o ); - _valid = o._valid; - } - - optional( const optional& o ) - :_valid(false) - { - if( o._valid ) new (ptr()) T( *o ); - _valid = o._valid; - } - - optional( optional&& o ) - :_valid(false) - { - if( o._valid ) new (ptr()) T( fc::move(*o) ); - _valid = o._valid; - o.reset(); - } - - template - optional( const optional& o ) - :_valid(false) - { - if( o._valid ) new (ptr()) T( *o ); - _valid = o._valid; - } - - template - optional( optional& o ) - :_valid(false) - { - if( o._valid ) - { - new (ptr()) T( *o ); - } - _valid = o._valid; - } - - template - optional( optional&& o ) - :_valid(false) - { - if( o._valid ) new (ptr()) T( fc::move(*o) ); - _valid = o._valid; - o.reset(); - } - - template - optional( U&& u ) - :_valid(true) - { - new ((char*)ptr()) T( fc::forward(u) ); - } - - template - optional& operator=( U&& u ) - { - reset(); - new (ptr()) T( fc::forward(u) ); - _valid = true; - return *this; - } - - template - void emplace(Args&& ... args) { - if (_valid) { - reset(); - } - - new ((char*)ptr()) T( fc::forward(args)... ); - _valid = true; - } - - template - optional& operator=( optional& o ) { - if (this != &o) { - if( _valid && o._valid ) { - ref() = *o; - } else if( !_valid && o._valid ) { - new (ptr()) T( *o ); - _valid = true; - } else if (_valid) { - reset(); - } - } - return *this; - } - template - optional& operator=( const optional& o ) { - if (this != &o) { - if( _valid && o._valid ) { - ref() = *o; - } else if( !_valid && o._valid ) { - new (ptr()) T( *o ); - _valid = true; - } else if (_valid) { - reset(); - } - } - return *this; - } - - optional& operator=( optional& o ) { - if (this != &o) { - if( _valid && o._valid ) { - ref() = *o; - } else if( !_valid && o._valid ) { - new (ptr()) T( *o ); - _valid = true; - } else if (_valid) { - reset(); - } - } - return *this; - } - - optional& operator=( const optional& o ) { - if (this != &o) { - if( _valid && o._valid ) { - ref() = *o; - } else if( !_valid && o._valid ) { - new (ptr()) T( *o ); - _valid = true; - } else if (_valid) { - reset(); - } - } - return *this; - } - - template - optional& operator=( optional&& o ) - { - if (this != &o) - { - if( _valid && o._valid ) - { - ref() = fc::move(*o); - o.reset(); - } else if ( !_valid && o._valid ) { - *this = fc::move(*o); - } else if (_valid) { - reset(); - } - } - return *this; - } - - optional& operator=( optional&& o ) - { - if (this != &o) - { - if( _valid && o._valid ) - { - ref() = fc::move(*o); - o.reset(); - } else if ( !_valid && o._valid ) { - *this = fc::move(*o); - } else if (_valid) { - reset(); - } - } - return *this; - } - - bool valid()const { return _valid; } - bool operator!()const { return !_valid; } - - // this operation is not safe and can result in unintential - // casts and comparisons, use valid() or !! - explicit operator bool()const { return _valid; } - - T& operator*() { assert(_valid); return ref(); } - const T& operator*()const { assert(_valid); return ref(); } - - T* operator->() - { - assert(_valid); - return ptr(); - } - const T* operator->()const - { - assert(_valid); - return ptr(); - } - - optional& operator=(std::nullptr_t) - { - reset(); - return *this; - } - - friend bool operator < ( const optional a, optional b ) - { - if( a.valid() && b.valid() ) return *a < *b; - return a.valid() < b.valid(); - } - friend bool operator == ( const optional a, optional b ) - { - if( a.valid() && b.valid() ) return *a == *b; - return a.valid() == b.valid(); - } - - void reset() - { - if( _valid ) - { - ref().~T(); // cal destructor - } - _valid = false; - } - private: - template friend class optional; - T& ref() { return *ptr(); } - const T& ref()const { return *ptr(); } - T* ptr() { return reinterpret_cast(&_value); } - const T* ptr()const { return reinterpret_cast(&_value); } - - bool _valid; - storage_type _value; - }; - - template - bool operator == ( const optional& left, const optional& right ) { - return (!left == !right) || (!!left && *left == *right); - } - template - bool operator == ( const optional& left, const U& u ) { - return !!left && *left == u; - } - template - bool operator != ( const optional& left, const optional& right ) { - return (!left != !right) || (!!left && *left != *right); - } - template - bool operator != ( const optional& left, const U& u ) { - return !left || *left != u; - } - -#ifdef _MSC_VER -# pragma warning(pop) -#endif - -} // namespace fc From fdb27a41f5d2c94e09516ba63e1e9851b115cf13 Mon Sep 17 00:00:00 2001 From: Timothy Banks Date: Wed, 17 Jun 2020 09:50:10 -0400 Subject: [PATCH 019/124] Made std::optional to fc::variant conversion explicit --- include/fc/variant.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/fc/variant.hpp b/include/fc/variant.hpp index 9c372e3c8..f261076da 100644 --- a/include/fc/variant.hpp +++ b/include/fc/variant.hpp @@ -348,7 +348,7 @@ namespace fc } template - variant( const std::optional& v ) + explicit variant( const std::optional& v ) { memset( this, 0, sizeof(*this) ); if( v.has_value() ) *this = variant(*v); From 7ce1e02ea8b53ec43c7e02a74b73be504732e009 Mon Sep 17 00:00:00 2001 From: Timothy Banks Date: Wed, 17 Jun 2020 13:04:26 -0400 Subject: [PATCH 020/124] Remove many uses of has_value() on std::optional. --- include/fc/io/raw.hpp | 4 ++-- include/fc/reflect/variant.hpp | 2 +- include/fc/variant.hpp | 2 +- src/filesystem.cpp | 4 ++-- src/log/gelf_appender.cpp | 4 ++-- src/log/logger_config.cpp | 4 ++-- src/network/http/http_client.cpp | 4 ++-- src/network/url.cpp | 14 +++++++------- 8 files changed, 19 insertions(+), 19 deletions(-) diff --git a/include/fc/io/raw.hpp b/include/fc/io/raw.hpp index 834e720d1..41a4dc1de 100644 --- a/include/fc/io/raw.hpp +++ b/include/fc/io/raw.hpp @@ -268,8 +268,8 @@ namespace fc { // optional template void pack( Stream& s, const std::optional& v ) { - fc::raw::pack( s, v.has_value() ); - if( v.has_value() ) fc::raw::pack( s, *v ); + fc::raw::pack( s, v ); + if( v ) fc::raw::pack( s, *v ); } template diff --git a/include/fc/reflect/variant.hpp b/include/fc/reflect/variant.hpp index c3089b4cb..15b4e309b 100644 --- a/include/fc/reflect/variant.hpp +++ b/include/fc/reflect/variant.hpp @@ -27,7 +27,7 @@ namespace fc template void add( mutable_variant_object& vo, const char* name, const std::optional& v )const { - if( v.has_value() ) + if( v ) vo(name,*v); } template diff --git a/include/fc/variant.hpp b/include/fc/variant.hpp index f261076da..aecec2026 100644 --- a/include/fc/variant.hpp +++ b/include/fc/variant.hpp @@ -351,7 +351,7 @@ namespace fc explicit variant( const std::optional& v ) { memset( this, 0, sizeof(*this) ); - if( v.has_value() ) *this = variant(*v); + if( v ) *this = variant(*v); } template diff --git a/src/filesystem.cpp b/src/filesystem.cpp index a32cbae20..1b8df2018 100644 --- a/src/filesystem.cpp +++ b/src/filesystem.cpp @@ -421,7 +421,7 @@ namespace fc { const fc::path& temp_file_base::path() const { - if (!_path.has_value()) + if (!_path) { FC_THROW( "Temporary directory has been released." ); } @@ -430,7 +430,7 @@ namespace fc { void temp_file_base::remove() { - if (_path.has_value()) + if (_path) { try { diff --git a/src/log/gelf_appender.cpp b/src/log/gelf_appender.cpp index 74e2e4b44..cc180773b 100644 --- a/src/log/gelf_appender.cpp +++ b/src/log/gelf_appender.cpp @@ -60,7 +60,7 @@ namespace fc catch (...) { } - if (!my->gelf_endpoint.has_value()) + if (!my->gelf_endpoint) { // couldn't parse as a numeric ip address, try resolving as a DNS name. // This can yield, so don't do it in the catch block above @@ -100,7 +100,7 @@ namespace fc void gelf_appender::log(const log_message& message) { - if (!my->gelf_endpoint.has_value()) + if (!my->gelf_endpoint) return; log_context context = message.get_context(); diff --git a/src/log/logger_config.cpp b/src/log/logger_config.cpp index 4d2ef776a..586909671 100644 --- a/src/log/logger_config.cpp +++ b/src/log/logger_config.cpp @@ -81,11 +81,11 @@ namespace fc { auto lgr = log_config::get().logger_map[cfg.loggers[i].name]; // TODO: finish configure logger here... - if( cfg.loggers[i].parent.has_value() ) { + if( cfg.loggers[i].parent ) { lgr.set_parent( log_config::get().logger_map[*cfg.loggers[i].parent] ); } lgr.set_name(cfg.loggers[i].name); - if( cfg.loggers[i].level.has_value() ) lgr.set_log_level( *cfg.loggers[i].level ); + if( cfg.loggers[i].level ) lgr.set_log_level( *cfg.loggers[i].level ); for( auto a = cfg.loggers[i].appenders.begin(); a != cfg.loggers[i].appenders.end(); ++a ){ diff --git a/src/network/http/http_client.cpp b/src/network/http/http_client.cpp index cf1e07a04..0718ef30a 100644 --- a/src/network/http/http_client.cpp +++ b/src/network/http/http_client.cpp @@ -158,7 +158,7 @@ class http_client_impl { } host_key url_to_host_key( const url& dest ) { - FC_ASSERT(dest.host().has_value(), "Provided URL has no host"); + FC_ASSERT(dest.host(), "Provided URL has no host"); uint16_t port = 80; if (dest.port()) { port = *dest.port(); @@ -316,7 +316,7 @@ class http_client_impl { variant post_sync(const url& dest, const variant& payload, const fc::time_point& _deadline) { static const deadline_type epoch(boost::gregorian::date(1970, 1, 1)); auto deadline = epoch + boost::posix_time::microseconds(_deadline.time_since_epoch().count()); - FC_ASSERT(dest.host().has_value(), "No host set on URL"); + FC_ASSERT(dest.host(), "No host set on URL"); string path = dest.path() ? dest.path()->generic_string() : "/"; if (dest.query()) { diff --git a/src/network/url.cpp b/src/network/url.cpp index 29c247974..448fd263f 100644 --- a/src/network/url.cpp +++ b/src/network/url.cpp @@ -60,7 +60,7 @@ namespace fc _path = fc::path( "/" ) / _lpath; #endif std::getline( ss, _largs ); - if( _args.has_value() && _args->size() ) + if( _args && _args->size() ) { // TODO: args = fc::move(_args); _query = fc::move(_largs); @@ -91,17 +91,17 @@ namespace fc { std::stringstream ss; ss<_proto<<"://"; - if( my->_user.has_value() ) { + if( my->_user ) { ss << *my->_user; - if( my->_pass.has_value() ) { + if( my->_pass ) { ss<<":"<<*my->_pass; } ss<<"@"; } - if( my->_host.has_value() ) ss<<*my->_host; - if( my->_port.has_value() ) ss<<":"<<*my->_port; - if( my->_path.has_value() ) ss<_path->generic_string(); - if( my->_query.has_value() ) ss<<"?"<<*my->_query; + if( my->_host ) ss<<*my->_host; + if( my->_port ) ss<<":"<<*my->_port; + if( my->_path ) ss<_path->generic_string(); + if( my->_query ) ss<<"?"<<*my->_query; // if( my->_args ) ss<<"?"<<*my->_args; return ss.str(); } From b810bafb3c0f61a8d22c9c425ed65b00eb584c79 Mon Sep 17 00:00:00 2001 From: Timothy Banks Date: Thu, 18 Jun 2020 13:37:19 -0400 Subject: [PATCH 021/124] Fixed infinite recursive all --- include/fc/io/raw.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/fc/io/raw.hpp b/include/fc/io/raw.hpp index 41a4dc1de..e206c4c67 100644 --- a/include/fc/io/raw.hpp +++ b/include/fc/io/raw.hpp @@ -268,7 +268,7 @@ namespace fc { // optional template void pack( Stream& s, const std::optional& v ) { - fc::raw::pack( s, v ); + fc::raw::pack( s, v.has_value() ); if( v ) fc::raw::pack( s, *v ); } From edc557b0cd01b4ab71c65b66ceca428642887fe6 Mon Sep 17 00:00:00 2001 From: Timothy Banks Date: Thu, 18 Jun 2020 16:21:56 -0400 Subject: [PATCH 022/124] Prefer std::make_optional --- include/fc/variant.hpp | 2 +- src/filesystem.cpp | 2 +- src/network/gntp.cpp | 12 ++++++------ src/network/ntp.cpp | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/include/fc/variant.hpp b/include/fc/variant.hpp index aecec2026..f8d3dcadb 100644 --- a/include/fc/variant.hpp +++ b/include/fc/variant.hpp @@ -391,7 +391,7 @@ namespace fc template void from_variant( const variant& var, std::optional& vo ) { - if( var.is_null() ) vo = std::optional(); + if( var.is_null() ) vo = std::make_optional(); else { vo = T(); diff --git a/src/filesystem.cpp b/src/filesystem.cpp index 1b8df2018..435a16f48 100644 --- a/src/filesystem.cpp +++ b/src/filesystem.cpp @@ -446,7 +446,7 @@ namespace fc { void temp_file_base::release() { - _path = std::optional(); + _path = std::make_optional(); } const fc::path& home_path() diff --git a/src/network/gntp.cpp b/src/network/gntp.cpp index 0c522d313..60522a659 100644 --- a/src/network/gntp.cpp +++ b/src/network/gntp.cpp @@ -45,7 +45,7 @@ namespace fc class gntp_notifier_impl { public: - gntp_notifier_impl(const std::string& host_to_notify = "127.0.0.1", uint16_t port = 23053, const std::optional& password = std::optional()); + gntp_notifier_impl(const std::string& host_to_notify = "127.0.0.1", uint16_t port = 23053, const std::optional& password = std::make_optional()); // there's no API to change these right now, it will always notify localhost at the default GNTP port std::string hostname; @@ -66,7 +66,7 @@ namespace fc }; gntp_notifier_impl::gntp_notifier_impl(const std::string& host_to_notify /* = "127.0.0.1" */, uint16_t port /* = 23053 */, - const std::optional& password /* = std::optional() */) : + const std::optional& password /* = std::make_optional() */) : hostname(host_to_notify), port(port), password(password), @@ -94,14 +94,14 @@ namespace fc ("error_report", er.to_detail_string())); sock->close(); // clear the cached endpoint and fall through to the full connection procedure - endpoint = std::optional(); + endpoint = std::make_optional(); } catch (...) { ilog("Failed to connect to GNTP service using an endpoint that previously worked"); sock->close(); // clear the cached endpoint and fall through to the full connection procedure - endpoint = std::optional(); + endpoint = std::make_optional(); } } if (!connected) @@ -165,7 +165,7 @@ namespace fc } gntp_notifier::gntp_notifier(const std::string& host_to_notify /* = "127.0.0.1" */, uint16_t port /* = 23053 */, - const std::optional& password /* = std::optional() */) : + const std::optional& password /* = std::make_optional() */) : my(new detail::gntp_notifier_impl(host_to_notify, port, password)) { } @@ -243,7 +243,7 @@ namespace fc } } gntp_guid gntp_notifier::send_notification(std::string name, std::string title, std::string text, - const gntp_icon_ptr& icon, std::optional coalescingId /* = std::optional() */) + const gntp_icon_ptr& icon, std::optional coalescingId /* = std::make_optional() */) { if (my->connection_failed) return gntp_guid(); diff --git a/src/network/ntp.cpp b/src/network/ntp.cpp index 00aeadf87..d68e5899c 100644 --- a/src/network/ntp.cpp +++ b/src/network/ntp.cpp @@ -247,7 +247,7 @@ namespace fc { if( my->_last_ntp_delta_initialized ) return fc::time_point::now() + fc::microseconds(my->_last_ntp_delta_microseconds); - return std::optional(); + return std::make_optional(); } } //namespace fc From 3f14defacb38ac28bb7dce4c6ad4a7c5049ac990 Mon Sep 17 00:00:00 2001 From: Timothy Banks Date: Tue, 23 Jun 2020 14:46:53 -0400 Subject: [PATCH 023/124] Rollback overzealous use of std::make_optional --- include/fc/variant.hpp | 4 ++-- src/filesystem.cpp | 2 +- src/network/gntp.cpp | 12 ++++++------ src/network/ntp.cpp | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/include/fc/variant.hpp b/include/fc/variant.hpp index f8d3dcadb..f261076da 100644 --- a/include/fc/variant.hpp +++ b/include/fc/variant.hpp @@ -351,7 +351,7 @@ namespace fc explicit variant( const std::optional& v ) { memset( this, 0, sizeof(*this) ); - if( v ) *this = variant(*v); + if( v.has_value() ) *this = variant(*v); } template @@ -391,7 +391,7 @@ namespace fc template void from_variant( const variant& var, std::optional& vo ) { - if( var.is_null() ) vo = std::make_optional(); + if( var.is_null() ) vo = std::optional(); else { vo = T(); diff --git a/src/filesystem.cpp b/src/filesystem.cpp index 435a16f48..1b8df2018 100644 --- a/src/filesystem.cpp +++ b/src/filesystem.cpp @@ -446,7 +446,7 @@ namespace fc { void temp_file_base::release() { - _path = std::make_optional(); + _path = std::optional(); } const fc::path& home_path() diff --git a/src/network/gntp.cpp b/src/network/gntp.cpp index 60522a659..0c522d313 100644 --- a/src/network/gntp.cpp +++ b/src/network/gntp.cpp @@ -45,7 +45,7 @@ namespace fc class gntp_notifier_impl { public: - gntp_notifier_impl(const std::string& host_to_notify = "127.0.0.1", uint16_t port = 23053, const std::optional& password = std::make_optional()); + gntp_notifier_impl(const std::string& host_to_notify = "127.0.0.1", uint16_t port = 23053, const std::optional& password = std::optional()); // there's no API to change these right now, it will always notify localhost at the default GNTP port std::string hostname; @@ -66,7 +66,7 @@ namespace fc }; gntp_notifier_impl::gntp_notifier_impl(const std::string& host_to_notify /* = "127.0.0.1" */, uint16_t port /* = 23053 */, - const std::optional& password /* = std::make_optional() */) : + const std::optional& password /* = std::optional() */) : hostname(host_to_notify), port(port), password(password), @@ -94,14 +94,14 @@ namespace fc ("error_report", er.to_detail_string())); sock->close(); // clear the cached endpoint and fall through to the full connection procedure - endpoint = std::make_optional(); + endpoint = std::optional(); } catch (...) { ilog("Failed to connect to GNTP service using an endpoint that previously worked"); sock->close(); // clear the cached endpoint and fall through to the full connection procedure - endpoint = std::make_optional(); + endpoint = std::optional(); } } if (!connected) @@ -165,7 +165,7 @@ namespace fc } gntp_notifier::gntp_notifier(const std::string& host_to_notify /* = "127.0.0.1" */, uint16_t port /* = 23053 */, - const std::optional& password /* = std::make_optional() */) : + const std::optional& password /* = std::optional() */) : my(new detail::gntp_notifier_impl(host_to_notify, port, password)) { } @@ -243,7 +243,7 @@ namespace fc } } gntp_guid gntp_notifier::send_notification(std::string name, std::string title, std::string text, - const gntp_icon_ptr& icon, std::optional coalescingId /* = std::make_optional() */) + const gntp_icon_ptr& icon, std::optional coalescingId /* = std::optional() */) { if (my->connection_failed) return gntp_guid(); diff --git a/src/network/ntp.cpp b/src/network/ntp.cpp index d68e5899c..00aeadf87 100644 --- a/src/network/ntp.cpp +++ b/src/network/ntp.cpp @@ -247,7 +247,7 @@ namespace fc { if( my->_last_ntp_delta_initialized ) return fc::time_point::now() + fc::microseconds(my->_last_ntp_delta_microseconds); - return std::make_optional(); + return std::optional(); } } //namespace fc From d65ca1ffe832052a9061da523fc320440c5a3e1a Mon Sep 17 00:00:00 2001 From: Timothy Banks Date: Tue, 21 Jul 2020 12:41:46 -0400 Subject: [PATCH 024/124] Formatting corrections --- include/fc/log/logger_config.hpp | 4 ++-- include/fc/network/url.hpp | 2 +- src/log/gelf_appender.cpp | 4 ++-- src/network/url.cpp | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/include/fc/log/logger_config.hpp b/include/fc/log/logger_config.hpp index 8d021cdc5..04de647d5 100644 --- a/include/fc/log/logger_config.hpp +++ b/include/fc/log/logger_config.hpp @@ -28,11 +28,11 @@ namespace fc { string name; ostring parent; /// if not set, then parents level is used. - std::optional level; + std::optional level; bool enabled; /// if any appenders are sepecified, then parent's appenders are not set. bool additivity; - std::vector appenders; + std::vector appenders; }; struct logging_config { diff --git a/include/fc/network/url.hpp b/include/fc/network/url.hpp index 217f4e611..c9cd47ce8 100644 --- a/include/fc/network/url.hpp +++ b/include/fc/network/url.hpp @@ -48,7 +48,7 @@ namespace fc { opath path()const; ostring query()const; ovariant_object args()const; - std::optional port()const; + std::optional port()const; private: friend class mutable_url; diff --git a/src/log/gelf_appender.cpp b/src/log/gelf_appender.cpp index cc180773b..8a7b810ce 100644 --- a/src/log/gelf_appender.cpp +++ b/src/log/gelf_appender.cpp @@ -29,9 +29,9 @@ namespace fc class gelf_appender::impl { public: - config cfg; + config cfg; std::optional gelf_endpoint; - udp_socket gelf_socket; + udp_socket gelf_socket; impl(const config& c) : cfg(c) diff --git a/src/network/url.cpp b/src/network/url.cpp index 448fd263f..defc2ab7c 100644 --- a/src/network/url.cpp +++ b/src/network/url.cpp @@ -74,7 +74,7 @@ namespace fc opath _path; ostring _query; ovariant_object _args; - std::optional _port; + std::optional _port; }; } @@ -191,7 +191,7 @@ namespace fc { return my->_args; } - std::optional url::port()const + std::optional url::port()const { return my->_port; } From eb4a4a4f75dd4a0c2b4cf374f38a21767e2d8bcc Mon Sep 17 00:00:00 2001 From: Timothy Banks Date: Mon, 22 Jun 2020 11:35:53 -0400 Subject: [PATCH 025/124] Migrate to std::variant --- include/fc/crypto/common.hpp | 24 +- include/fc/crypto/private_key.hpp | 2 +- include/fc/crypto/public_key.hpp | 2 +- include/fc/crypto/signature.hpp | 2 +- include/fc/io/raw.hpp | 13 +- include/fc/io/raw_fwd.hpp | 8 +- include/fc/rpc/json_connection.hpp | 264 ++++---- include/fc/rpc/variant_connection.hpp | 38 +- include/fc/rpc/variant_stream.hpp | 2 +- include/fc/static_variant.hpp | 639 +++----------------- include/fc/variant.hpp | 283 +++++---- src/crypto/private_key.cpp | 19 +- src/crypto/public_key.cpp | 12 +- src/crypto/signature.cpp | 14 +- src/network/http/http_client.cpp | 11 +- src/rpc/json_connection.cpp | 122 ++-- src/rpc/state.cpp | 2 +- test/static_variant/test_static_variant.cpp | 131 ++-- 18 files changed, 545 insertions(+), 1043 deletions(-) diff --git a/include/fc/crypto/common.hpp b/include/fc/crypto/common.hpp index aa63d808d..bde348efb 100644 --- a/include/fc/crypto/common.hpp +++ b/include/fc/crypto/common.hpp @@ -72,8 +72,8 @@ namespace fc { namespace crypto { * @return */ template - struct base58_str_parser, Prefixes> { - static fc::static_variant apply(const std::string& base58str) { + struct base58_str_parser, Prefixes> { + static std::variant apply(const std::string& base58str) { const auto pivot = base58str.find('_'); FC_ASSERT(pivot != std::string::npos, "No delimiter in data, cannot determine suite type: ${str}", ("str", base58str)); @@ -81,7 +81,7 @@ namespace fc { namespace crypto { auto data_str = base58str.substr(pivot + 1); FC_ASSERT(!data_str.empty(), "Data only has suite type prefix: ${str}", ("str", base58str)); - return base58_str_parser_impl, Prefixes, 0, Ts...>::apply(prefix_str, data_str); + return base58_str_parser_impl, Prefixes, 0, Ts...>::apply(prefix_str, data_str); } }; @@ -92,7 +92,7 @@ namespace fc { namespace crypto { template< typename KeyType > std::string operator()( const KeyType& key ) const { using data_type = typename KeyType::data_type; - constexpr int position = Storage::template position(); + constexpr int position = fc::get_index(); constexpr bool is_default = position == DefaultPosition; checksummed_data wrapper; @@ -122,15 +122,15 @@ namespace fc { namespace crypto { }; template - struct eq_comparator> { - using variant_type = fc::static_variant; + struct eq_comparator> { + using variant_type = std::variant; struct visitor : public fc::visitor { visitor(const variant_type &b) : _b(b) {} template bool operator()(const KeyType &a) const { - const auto &b = _b.template get(); + const auto &b = std::template get(_b); return eq_comparator::apply(a,b); } @@ -138,7 +138,7 @@ namespace fc { namespace crypto { }; static bool apply(const variant_type& a, const variant_type& b) { - return a.which() == b.which() && a.visit(visitor(b)); + return a.index() == b.index() && std::visit(visitor(b), a); } }; @@ -150,15 +150,15 @@ namespace fc { namespace crypto { }; template - struct less_comparator> { - using variant_type = fc::static_variant; + struct less_comparator> { + using variant_type = std::variant; struct visitor : public fc::visitor { visitor(const variant_type &b) : _b(b) {} template bool operator()(const KeyType &a) const { - const auto &b = _b.template get(); + const auto &b = std::template get(_b); return less_comparator::apply(a,b); } @@ -166,7 +166,7 @@ namespace fc { namespace crypto { }; static bool apply(const variant_type& a, const variant_type& b) { - return a.which() < b.which() || (a.which() == b.which() && a.visit(visitor(b))); + return a.index() < b.index() || (a.index() == b.index() && std::visit(visitor(b), a)); } }; diff --git a/include/fc/crypto/private_key.hpp b/include/fc/crypto/private_key.hpp index d986abca4..505bf3d3d 100644 --- a/include/fc/crypto/private_key.hpp +++ b/include/fc/crypto/private_key.hpp @@ -19,7 +19,7 @@ namespace fc { namespace crypto { class private_key { public: - using storage_type = static_variant; + using storage_type = std::variant; private_key() = default; private_key( private_key&& ) = default; diff --git a/include/fc/crypto/public_key.hpp b/include/fc/crypto/public_key.hpp index b881259aa..bee8215c8 100644 --- a/include/fc/crypto/public_key.hpp +++ b/include/fc/crypto/public_key.hpp @@ -21,7 +21,7 @@ namespace fc { namespace crypto { class public_key { public: - using storage_type = static_variant; + using storage_type = std::variant; public_key() = default; public_key( public_key&& ) = default; diff --git a/include/fc/crypto/signature.hpp b/include/fc/crypto/signature.hpp index 53a2a2fae..a4405193c 100644 --- a/include/fc/crypto/signature.hpp +++ b/include/fc/crypto/signature.hpp @@ -19,7 +19,7 @@ namespace fc { namespace crypto { class signature { public: - using storage_type = static_variant; + using storage_type = std::variant; signature() = default; signature( signature&& ) = default; diff --git a/include/fc/io/raw.hpp b/include/fc/io/raw.hpp index e206c4c67..7f61d8a2e 100644 --- a/include/fc/io/raw.hpp +++ b/include/fc/io/raw.hpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -766,18 +767,18 @@ namespace fc { template - void pack( Stream& s, const static_variant& sv ) + void pack( Stream& s, const std::variant& sv ) { - fc::raw::pack( s, unsigned_int(sv.which()) ); - sv.visit( pack_static_variant(s) ); + fc::raw::pack( s, unsigned_int(sv.index()) ); + std::visit( pack_static_variant(s), sv ); } - template void unpack( Stream& s, static_variant& sv ) + template void unpack( Stream& s, std::variant& sv ) { unsigned_int w; fc::raw::unpack( s, w ); - sv.set_which(w.value); - sv.visit( unpack_static_variant(s) ); + fc::from_index(sv, w.value); + std::visit( unpack_static_variant(s), sv ); } diff --git a/include/fc/io/raw_fwd.hpp b/include/fc/io/raw_fwd.hpp index e71d26ec3..60acfc724 100644 --- a/include/fc/io/raw_fwd.hpp +++ b/include/fc/io/raw_fwd.hpp @@ -10,6 +10,7 @@ #include #include #include +#include namespace fc { class time_point; @@ -17,8 +18,7 @@ namespace fc { class variant; class variant_object; class path; - template class static_variant; - + template class enum_type; namespace ip { class endpoint; } @@ -47,8 +47,8 @@ namespace fc { template inline void pack( Stream& s, const std::unordered_set& value ); template inline void unpack( Stream& s, std::unordered_set& value ); - template void pack( Stream& s, const static_variant& sv ); - template void unpack( Stream& s, static_variant& sv ); + template void pack( Stream& s, const std::variant& sv ); + template void unpack( Stream& s, std::variant& sv ); template inline void pack( Stream& s, const std::deque& value ); template inline void unpack( Stream& s, std::deque& value ); diff --git a/include/fc/rpc/json_connection.hpp b/include/fc/rpc/json_connection.hpp index 04cd041b0..67f323a04 100644 --- a/include/fc/rpc/json_connection.hpp +++ b/include/fc/rpc/json_connection.hpp @@ -58,92 +58,92 @@ namespace fc { namespace rpc { void notice( const fc::string& method, const variant_object& named_args ); /// args will be handled as named params - future async_call( const fc::string& method, + future async_call( const fc::string& method, const variant_object& args ); - future async_call( const fc::string& method, mutable_variant_object args ); + future async_call( const fc::string& method, mutable_variant_object args ); /// Sending in an array of variants will be handled as positional arguments - future async_call( const fc::string& method, + future async_call( const fc::string& method, const variants& args ); - future async_call( const fc::string& method ); - - future async_call( const fc::string& method, - const variant& a1 ); - - future async_call( const fc::string& method, - const variant& a1, - const variant& a2 ); - - future async_call( const fc::string& method, - const variant& a1, - const variant& a2, - const variant& a3 ); - - future async_call( const fc::string& method, - const variant& a1, - const variant& a2, - const variant& a3, - const variant& a4 ); - - future async_call( const fc::string& method, - const variant& a1, - const variant& a2, - const variant& a3, - const variant& a4, - const variant& a5 ); - - future async_call( const fc::string& method, - const variant& a1, - const variant& a2, - const variant& a3, - const variant& a4, - const variant& a5, - const variant& a6 ); - - future async_call( const fc::string& method, - const variant& a1, - const variant& a2, - const variant& a3, - const variant& a4, - const variant& a5, - const variant& a6, - const variant& a7 + future async_call( const fc::string& method ); + + future async_call( const fc::string& method, + const fc::variant& a1 ); + + future async_call( const fc::string& method, + const fc::variant& a1, + const fc::variant& a2 ); + + future async_call( const fc::string& method, + const fc::variant& a1, + const fc::variant& a2, + const fc::variant& a3 ); + + future async_call( const fc::string& method, + const fc::variant& a1, + const fc::variant& a2, + const fc::variant& a3, + const fc::variant& a4 ); + + future async_call( const fc::string& method, + const fc::variant& a1, + const fc::variant& a2, + const fc::variant& a3, + const fc::variant& a4, + const fc::variant& a5 ); + + future async_call( const fc::string& method, + const fc::variant& a1, + const fc::variant& a2, + const fc::variant& a3, + const fc::variant& a4, + const fc::variant& a5, + const fc::variant& a6 ); + + future async_call( const fc::string& method, + const fc::variant& a1, + const fc::variant& a2, + const fc::variant& a3, + const fc::variant& a4, + const fc::variant& a5, + const fc::variant& a6, + const fc::variant& a7 ); - future async_call( const fc::string& method, - const variant& a1, - const variant& a2, - const variant& a3, - const variant& a4, - const variant& a5, - const variant& a6, - const variant& a7, - const variant& a8 + future async_call( const fc::string& method, + const fc::variant& a1, + const fc::variant& a2, + const fc::variant& a3, + const fc::variant& a4, + const fc::variant& a5, + const fc::variant& a6, + const fc::variant& a7, + const fc::variant& a8 ); - future async_call( const fc::string& method, - const variant& a1, - const variant& a2, - const variant& a3, - const variant& a4, - const variant& a5, - const variant& a6, - const variant& a7, - const variant& a8, - const variant& a9 + future async_call( const fc::string& method, + const fc::variant& a1, + const fc::variant& a2, + const fc::variant& a3, + const fc::variant& a4, + const fc::variant& a5, + const fc::variant& a6, + const fc::variant& a7, + const fc::variant& a8, + const fc::variant& a9 ); - future async_call( const fc::string& method, - const variant& a1, - const variant& a2, - const variant& a3, - const variant& a4, - const variant& a5, - const variant& a6, - const variant& a7, - const variant& a8, - const variant& a9, - const variant& a10 + future async_call( const fc::string& method, + const fc::variant& a1, + const fc::variant& a2, + const fc::variant& a3, + const fc::variant& a4, + const fc::variant& a5, + const fc::variant& a6, + const fc::variant& a7, + const fc::variant& a8, + const fc::variant& a9, + const fc::variant& a10 ); template @@ -156,9 +156,9 @@ namespace fc { namespace rpc { template Result call( const fc::string& method, - const variant& a1, - const variant& a2, - const variant& a3, + const fc::variant& a1, + const fc::variant& a2, + const fc::variant& a3, microseconds timeout = microseconds::maximum()) { return async_call( method, a1, a2, a3 ).wait(timeout).as(); @@ -166,10 +166,10 @@ namespace fc { namespace rpc { template Result call( const fc::string& method, - const variant& a1, - const variant& a2, - const variant& a3, - const variant& a4, + const fc::variant& a1, + const fc::variant& a2, + const fc::variant& a3, + const fc::variant& a4, microseconds timeout = microseconds::maximum()) { return async_call( method, a1, a2, a3, a4).wait(timeout).as(); @@ -177,11 +177,11 @@ namespace fc { namespace rpc { template Result call( const fc::string& method, - const variant& a1, - const variant& a2, - const variant& a3, - const variant& a4, - const variant& a5, + const fc::variant& a1, + const fc::variant& a2, + const fc::variant& a3, + const fc::variant& a4, + const fc::variant& a5, microseconds timeout = microseconds::maximum()) { return async_call( method, a1, a2, a3, a4, a5).wait(timeout).as(); @@ -189,25 +189,25 @@ namespace fc { namespace rpc { template Result call( const fc::string& method, - const variant& a1, - const variant& a2, - const variant& a3, - const variant& a4, - const variant& a5, - const variant& a6, + const fc::variant& a1, + const fc::variant& a2, + const fc::variant& a3, + const fc::variant& a4, + const fc::variant& a5, + const fc::variant& a6, microseconds timeout = microseconds::maximum()) { return async_call( method, a1, a2, a3, a4, a5, a6).wait(timeout).as(); } template Result call( const fc::string& method, - const variant& a1, - const variant& a2, - const variant& a3, - const variant& a4, - const variant& a5, - const variant& a6, - const variant& a7, + const fc::variant& a1, + const fc::variant& a2, + const fc::variant& a3, + const fc::variant& a4, + const fc::variant& a5, + const fc::variant& a6, + const fc::variant& a7, microseconds timeout = microseconds::maximum()) { return async_call( method, a1, a2, a3, a4, a5, a6, a7).wait(timeout).as(); @@ -215,14 +215,14 @@ namespace fc { namespace rpc { template Result call( const fc::string& method, - const variant& a1, - const variant& a2, - const variant& a3, - const variant& a4, - const variant& a5, - const variant& a6, - const variant& a7, - const variant& a8, + const fc::variant& a1, + const fc::variant& a2, + const fc::variant& a3, + const fc::variant& a4, + const fc::variant& a5, + const fc::variant& a6, + const fc::variant& a7, + const fc::variant& a8, microseconds timeout = microseconds::maximum()) { return async_call( method, a1, a2, a3, a4, a5, a6, a7, a8).wait(timeout).as(); @@ -230,15 +230,15 @@ namespace fc { namespace rpc { template Result call( const fc::string& method, - const variant& a1, - const variant& a2, - const variant& a3, - const variant& a4, - const variant& a5, - const variant& a6, - const variant& a7, - const variant& a8, - const variant& a9, + const fc::variant& a1, + const fc::variant& a2, + const fc::variant& a3, + const fc::variant& a4, + const fc::variant& a5, + const fc::variant& a6, + const fc::variant& a7, + const fc::variant& a8, + const fc::variant& a9, microseconds timeout = microseconds::maximum()) { return async_call( method, a1, a2, a3, a4, a5, a6, a7, a8, a9).wait(timeout).as(); @@ -246,16 +246,16 @@ namespace fc { namespace rpc { template Result call( const fc::string& method, - const variant& a1, - const variant& a2, - const variant& a3, - const variant& a4, - const variant& a5, - const variant& a6, - const variant& a7, - const variant& a8, - const variant& a9, - const variant& a10, + const fc::variant& a1, + const fc::variant& a2, + const fc::variant& a3, + const fc::variant& a4, + const fc::variant& a5, + const fc::variant& a6, + const fc::variant& a7, + const fc::variant& a8, + const fc::variant& a9, + const fc::variant& a10, microseconds timeout = microseconds::maximum()) { return async_call( method, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10).wait(timeout).as(); @@ -263,8 +263,8 @@ namespace fc { namespace rpc { template Result call( const fc::string& method, - const variant& a1, - const variant& a2, + const fc::variant& a1, + const fc::variant& a2, microseconds timeout = microseconds::maximum()) { return async_call( method, a1, a2 ).wait(timeout).as(); @@ -272,7 +272,7 @@ namespace fc { namespace rpc { template Result call( const fc::string& method, - const variant& a1, + const fc::variant& a1, microseconds timeout = microseconds::maximum()) { return async_call( method, a1 ).wait(timeout).as(); @@ -301,7 +301,7 @@ namespace fc { namespace rpc { } /// Sending in a variant_object will be issued as named parameters - variant call( const fc::string& method, const variant_object& named_args ); + fc::variant call( const fc::string& method, const variant_object& named_args ); ///@} private: diff --git a/include/fc/rpc/variant_connection.hpp b/include/fc/rpc/variant_connection.hpp index 93cb29b1e..aa73ab717 100644 --- a/include/fc/rpc/variant_connection.hpp +++ b/include/fc/rpc/variant_connection.hpp @@ -53,34 +53,34 @@ namespace fc { namespace rpc { void notice( const fc::string& method, const variant_object& named_args ); /// args will be handled as named params - future async_call( const fc::string& method, + future async_call( const fc::string& method, const variant_object& args ); - future async_call( const fc::string& method, mutable_variant_object args ); + future async_call( const fc::string& method, mutable_variant_object args ); /// Sending in an array of variants will be handled as positional arguments - future async_call( const fc::string& method, + future async_call( const fc::string& method, const variants& args ); - future async_call( const fc::string& method ); + future async_call( const fc::string& method ); - future async_call( const fc::string& method, - const variant& a1 ); + future async_call( const fc::string& method, + const fc::variant& a1 ); - future async_call( const fc::string& method, - const variant& a1, - const variant& a2 ); + future async_call( const fc::string& method, + const fc::variant& a1, + const fc::variant& a2 ); - future async_call( const fc::string& method, - const variant& a1, - const variant& a2, - const variant& a3 ); + future async_call( const fc::string& method, + const fc::variant& a1, + const fc::variant& a2, + const fc::variant& a3 ); template Result call( const fc::string& method, - const variant& a1, - const variant& a2, - const variant& a3, + const fc::variant& a1, + const fc::variant& a2, + const fc::variant& a3, microseconds timeout = microseconds::maximum()) { return async_call( method, a1, a2, a3 ).wait(timeout).as(); @@ -88,8 +88,8 @@ namespace fc { namespace rpc { template Result call( const fc::string& method, - const variant& a1, - const variant& a2, + const fc::variant& a1, + const fc::variant& a2, microseconds timeout = microseconds::maximum()) { return async_call( method, a1, a2 ).wait(timeout).as(); @@ -97,7 +97,7 @@ namespace fc { namespace rpc { template Result call( const fc::string& method, - const variant& a1, + const fc::variant& a1, microseconds timeout = microseconds::maximum()) { return async_call( method, a1 ).wait(timeout).as(); diff --git a/include/fc/rpc/variant_stream.hpp b/include/fc/rpc/variant_stream.hpp index 585b776b0..9c9bc2e42 100644 --- a/include/fc/rpc/variant_stream.hpp +++ b/include/fc/rpc/variant_stream.hpp @@ -28,7 +28,7 @@ namespace fc int64_t wait(); // wait for variants to be posted private: - std::vector _variants; + std::vector _variants; uint64_t _read_pos; uint64_t _write_pos; }; diff --git a/include/fc/static_variant.hpp b/include/fc/static_variant.hpp index b7d047bda..0ca24ee57 100644 --- a/include/fc/static_variant.hpp +++ b/include/fc/static_variant.hpp @@ -14,587 +14,86 @@ #include #include #include +#include namespace fc { -// Implementation details, the user should not import this: -namespace impl { - -template -struct storage_ops; - -template -struct position; - -template -struct type_at; - -template -struct type_info; - -template< typename Visitor, typename ...Ts> -struct const_result_type_info; - -template< typename Visitor, typename ...Ts> -struct result_type_info; - -template< typename Visitor, typename ...Ts> -struct rvalue_ref_result_type_info; +// This will go away. +template +struct visitor {}; -template -struct copy_construct +template +void from_index(variant& v, int index) { - StaticVariant& sv; - copy_construct( StaticVariant& s ):sv(s){} - template - void operator()( const T& v )const - { - sv.init(v); - } -}; - -template -struct move_construct + if constexpr(I >= std::variant_size_v) + { + throw std::runtime_error{"Variant index " + std::to_string(I + index) + " out of bounds"}; + } + else if (index == 0) + { + auto value = variant(std::in_place_index); + v = std::move(value); + } + else + { + from_index(v, index - 1); + } +} + +template +constexpr std::size_t get_index() { - StaticVariant& sv; - move_construct( StaticVariant& s ):sv(s){} - template - void operator()( T& v )const - { - sv.init( std::move(v) ); - } -}; - -template -struct storage_ops { - static void del(int n, void *data) {} - static void con(int n, void *data) {} - - template - static R apply(int n, void *data, visitor&& v) {} - - template - static R apply(int n, const void *data, visitor&& v) {} - - template - static R apply_rvalue_ref(int n, void *data, visitor&& v) {} - - template class Op> - static R apply_binary_operator(int n, const void *lhs, const void *rhs) {} -}; - -template -struct storage_ops { - static void del(int n, void *data) { - if(n == N) reinterpret_cast(data)->~T(); - else storage_ops::del(n, data); - } - static void con(int n, void *data) { - if(n == N) new(reinterpret_cast(data)) T(); - else storage_ops::con(n, data); - } - - template - static R apply(int n, void *data, visitor&& v) { - if(n == N) return v(*reinterpret_cast(data)); - else return storage_ops::apply(n, data, std::forward(v)); - } - - template - static R apply(int n, const void *data, visitor&& v) { - if(n == N) return v(*reinterpret_cast(data)); - else return storage_ops::apply(n, data, std::forward(v)); - } - - template - static R apply_rvalue_ref(int n, void *data, visitor&& v) { - if(n == N) return v(std::move(*reinterpret_cast(data))); - else return storage_ops::apply(n, data, std::forward(v)); - } - - template class Op> - static R apply_binary_operator(int n, const void *lhs, const void *rhs) { - if (n == N) return Op()(*reinterpret_cast(lhs), *reinterpret_cast(rhs)); - else return storage_ops::template apply_binary_operator(n, lhs, rhs); - } -}; - -template -struct storage_ops { - static void del(int n, void *data) { - FC_THROW_EXCEPTION( fc::assert_exception, "Internal error: static_variant tag is invalid."); - } - static void con(int n, void *data) { - FC_THROW_EXCEPTION( fc::assert_exception, "Internal error: static_variant tag is invalid." ); - } - - template - static R apply(int n, void *data, visitor&& v) { - FC_THROW_EXCEPTION( fc::assert_exception, "Internal error: static_variant tag is invalid." ); - } - template - static R apply(int n, const void *data, visitor&& v) { - FC_THROW_EXCEPTION( fc::assert_exception, "Internal error: static_variant tag is invalid." ); - } - - template - static R apply_rvalue_ref(int n, void *data, visitor&& v) { - FC_THROW_EXCEPTION( fc::assert_exception, "Internal error: static_variant tag is invalid." ); - } - - template class Op> - static R apply_binary_operator(int n, const void *lhs, const void *rhs) { - FC_THROW_EXCEPTION( fc::assert_exception, "Internal error: static_variant tag is invalid." ); - } -}; - -template -using storage_ops_auto = storage_ops::result_type, N, Ts...>; - -template -using storage_ops_const_auto = storage_ops::result_type, N, Ts...>; - -template -using storage_ops_revalue_ref_auto = storage_ops::result_type, N, Ts...>; - -template -struct position { - static const int pos = -1; -}; - -template -struct position { - static const int pos = 0; -}; - -template -struct position { - static const int pos = position::pos != -1 ? position::pos + 1 : -1; -}; - -template -struct type_at<0, T, Ts...> { - using type = T; -}; - -template -struct type_at { - using type = typename type_at::type; -}; - -template class Op, typename T> -std::is_convertible, const T&, const T&>, bool> can_invoke_operator_test(int); - -template class Op, typename T> -std::false_type can_invoke_operator_test(...); - -template class Op, typename T> -using can_invoke_operator = decltype(can_invoke_operator_test(0)); - -template -struct type_info { - static const bool no_reference_types = false; - static const bool no_duplicates = position::pos == -1 && type_info::no_duplicates; - static const size_t size = type_info::size > sizeof(T&) ? type_info::size : sizeof(T&); - static const size_t count = 1 + type_info::count; - - static const bool has_equal_to = can_invoke_operator>::value && type_info::has_equal_to; - static const bool has_not_equal_to = can_invoke_operator>::value && type_info::has_not_equal_to; - static const bool has_less = can_invoke_operator>::value && type_info::has_less; - static const bool has_less_equal = can_invoke_operator>::value && type_info::has_less_equal; - static const bool has_greater = can_invoke_operator>::value && type_info::has_greater; - static const bool has_greater_equal = can_invoke_operator>::value && type_info::has_greater_equal; -}; - -template -struct type_info { - static const bool no_reference_types = type_info::no_reference_types; - static const bool no_duplicates = position::pos == -1 && type_info::no_duplicates; - static const size_t size = type_info::size > sizeof(T) ? type_info::size : sizeof(T&); - static const size_t count = 1 + type_info::count; - - static const bool has_equal_to = can_invoke_operator::value && type_info::has_equal_to; - static const bool has_not_equal_to = can_invoke_operator::value && type_info::has_not_equal_to; - static const bool has_less = can_invoke_operator::value && type_info::has_less; - static const bool has_less_equal = can_invoke_operator::value && type_info::has_less_equal; - static const bool has_greater = can_invoke_operator::value && type_info::has_greater; - static const bool has_greater_equal = can_invoke_operator::value && type_info::has_greater_equal; -}; - -template<> -struct type_info<> { - static const bool no_reference_types = true; - static const bool no_duplicates = true; - static const size_t count = 0; - static const size_t size = 0; - static const bool has_equal_to = true; - static const bool has_not_equal_to = true; - static const bool has_less = true; - static const bool has_less_equal = true; - static const bool has_greater = true; - static const bool has_greater_equal = true; -}; - -template -struct const_result_type_info { - using result_type = decltype(std::declval>()(std::declval())); -}; - -template -struct const_result_type_info { - using result_type = typename const_result_type_info::result_type; - - static_assert( - std::is_same_v::result_type >, - "Varying result types are not supported from visitors" - ); -}; - -template -struct result_type_info { - using result_type = decltype(std::declval>()(std::declval())); -}; - - -template -struct result_type_info { - using result_type = typename result_type_info::result_type; - - static_assert( - std::is_same_v::result_type >, - "Varying result types are not supported from visitors" - ); -}; - -template -struct rvalue_ref_result_type_info { - using result_type = decltype(std::declval>()(std::declval())); -}; - -template -struct rvalue_ref_result_type_info { - using result_type = typename rvalue_ref_result_type_info::result_type; + if constexpr (index == std::variant_size_v) + { + return index; + } + else if constexpr (std::is_same_v, T>) + { + return index; + } + else + { + return get_index(); + } +} + +struct from_static_variant +{ + variant& var; + from_static_variant( variant& dv ):var(dv){} - static_assert( - std::is_same_v::result_type >, - "Varying result types are not supported from visitors" - ); + template void operator()( const T& v )const + { + to_variant( v, var ); + } }; +struct to_static_variant +{ + const variant& var; + to_static_variant( const variant& dv ):var(dv){} -} // namespace impl - -template -class static_variant { - using type_info = impl::type_info; - static_assert(type_info::no_reference_types, "Reference types are not permitted in static_variant."); - static_assert(type_info::no_duplicates, "static_variant type arguments contain duplicate types."); - - alignas(Types...) char storage[impl::type_info::size]; - int _tag; - - template - void init(X&& x) { - _tag = impl::position, Types...>::pos; - new(storage) std::decay_t( std::forward(x) ); - } - - template - friend struct impl::copy_construct; - template - friend struct impl::move_construct; -public: - template - struct tag - { - static_assert( - impl::position::pos != -1, - "Type not in static_variant." - ); - static const int value = impl::position::pos; - }; - - static_variant() - { - _tag = 0; - impl::storage_ops::con(0, storage); - } - - template - static_variant( const static_variant& cpy ) - { - cpy.visit( impl::copy_construct(*this) ); - } - - static_variant( const static_variant& cpy ) - { - cpy.visit( impl::copy_construct(*this) ); - } - - static_variant( static_variant& cpy ) - : static_variant( const_cast(cpy) ) - {} - - static_variant( static_variant&& mv ) - { - mv.visit( impl::move_construct(*this) ); - } - - template - static_variant(X&& v) { - static_assert( - impl::position, Types...>::pos != -1, - "Type not in static_variant." - ); - init(std::forward(v)); - } - - ~static_variant() { - impl::storage_ops::del(_tag, storage); - } - - - template - static_variant& operator=(const X& v) { - static_assert( - impl::position::pos != -1, - "Type not in static_variant." - ); - this->~static_variant(); - init(v); - return *this; - } - static_variant& operator=( const static_variant& v ) - { - if( this == &v ) return *this; - this->~static_variant(); - v.visit( impl::copy_construct(*this) ); - return *this; - } - static_variant& operator=( static_variant&& v ) - { - if( this == &v ) return *this; - this->~static_variant(); - v.visit( impl::move_construct(*this) ); - return *this; - } - - template - friend std::enable_if_t operator == ( const static_variant& a, const static_variant& b ) - { - if (a.which() != b.which()) { - return false; - } - - return impl::storage_ops::template apply_binary_operator(a._tag, a.storage, b.storage); - } - - template - friend std::enable_if_t operator != ( const static_variant& a, const static_variant& b ) - { - if (a.which() != b.which()) { - return true; - } - - return impl::storage_ops::template apply_binary_operator(a._tag, a.storage, b.storage); - } - - template - friend std::enable_if_t operator < ( const static_variant& a, const static_variant& b ) - { - if (a.which() > b.which()) { - return false; - } - - if (a.which() < b.which()) { - return true; - } - - return impl::storage_ops::template apply_binary_operator(a._tag, a.storage, b.storage); - } - - template - friend std::enable_if_t operator <= ( const static_variant& a, const static_variant& b ) - { - if (a.which() > b.which()) { - return false; - } - - if (a.which() < b.which()) { - return true; - } - - return impl::storage_ops::template apply_binary_operator(a._tag, a.storage, b.storage); - } - - template - friend std::enable_if_t operator > ( const static_variant& a, const static_variant& b ) - { - if (a.which() < b.which()) { - return false; - } - - if (a.which() > b.which()) { - return true; - } - - return impl::storage_ops::template apply_binary_operator(a._tag, a.storage, b.storage); - } - - template - friend std::enable_if_t operator >= ( const static_variant& a, const static_variant& b ) - { - if (a.which() < b.which()) { - return false; - } - - if (a.which() > b.which()) { - return true; - } - - return impl::storage_ops::template apply_binary_operator(a._tag, a.storage, b.storage); - } - - template - X& get() & { - static_assert( - impl::position::pos != -1, - "Type not in static_variant." - ); - if(_tag == impl::position::pos) { - void* tmp(storage); - return *reinterpret_cast(tmp); - } else { - FC_THROW_EXCEPTION( fc::assert_exception, "static_variant does not contain a value of type ${t}", ("t",fc::get_typename::name()) ); - // std::string("static_variant does not contain value of type ") + typeid(X).name() - // ); - } - } - template - const X& get() const & { - static_assert( - impl::position::pos != -1, - "Type not in static_variant." - ); - if(_tag == impl::position::pos) { - const void* tmp(storage); - return *reinterpret_cast(tmp); - } else { - FC_THROW_EXCEPTION( fc::assert_exception, "static_variant does not contain a value of type ${t}", ("t",fc::get_typename::name()) ); - } - } - template - X&& get() && { - static_assert( - impl::position::pos != -1, - "Type not in static_variant." - ); - if(_tag == impl::position::pos) { - void* tmp(storage); - return std::move(*reinterpret_cast(tmp)); - } else { - FC_THROW_EXCEPTION( fc::assert_exception, "static_variant does not contain a value of type ${t}", ("t",fc::get_typename::name()) ); - } - } - template - auto visit(visitor&& v) & { - return impl::storage_ops_auto::apply(_tag, storage, std::forward(v)); - } - - - template - auto visit(visitor&& v) const & { - return impl::storage_ops_const_auto::apply(_tag, storage, std::forward(v)); - } - - template - auto visit(visitor&& v) && { - return impl::storage_ops_revalue_ref_auto::apply_rvalue_ref(_tag, storage, std::forward(v)); - } - - template - auto visit(visitor&& v) & { - return impl::storage_ops::apply(_tag, storage, std::forward(v)); - } - - - template - auto visit(visitor&& v) const & { - return impl::storage_ops::apply(_tag, storage, std::forward(v)); - } - - template - auto visit(visitor&& v) && { - return impl::storage_ops::apply_rvalue_ref(_tag, storage, std::forward(v)); - } - - static uint32_t count() { return type_info::count; } - void set_which( uint32_t w ) { - FC_ASSERT( w < count() ); - this->~static_variant(); - try { - _tag = w; - impl::storage_ops::con(_tag, storage); - } catch ( ... ) { - _tag = 0; - impl::storage_ops::con(_tag, storage); - } - } - - int which() const {return _tag;} - - template - bool contains() const { return which() == tag::value; } - - template - static constexpr int position() { return impl::position::pos; } - - template = 1> - using type_at = typename impl::type_at::type; -}; - -template -struct visitor { + template void operator()( T& v )const + { + from_variant( var, v ); + } }; - struct from_static_variant - { - variant& var; - from_static_variant( variant& dv ):var(dv){} - - template void operator()( const T& v )const - { - to_variant( v, var ); - } - }; - - struct to_static_variant - { - const variant& var; - to_static_variant( const variant& dv ):var(dv){} - - template void operator()( T& v )const - { - from_variant( var, v ); - } - }; - +template void to_variant( const std::variant& s, fc::variant& v ) +{ + variants vars(2); + vars[0] = s.index(); + visit( from_static_variant(vars[1]), s ); + v = std::move(vars); +} +template void from_variant( const fc::variant& v, std::variant& s ) +{ + auto ar = v.get_array(); + if( ar.size() < 2 ) return; + from_index(s, ar[0].as_uint64()); + visit( to_static_variant(ar[1]), s ); +} - template void to_variant( const fc::static_variant& s, fc::variant& v ) - { - variant tmp; - variants vars(2); - vars[0] = s.which(); - s.visit( from_static_variant(vars[1]) ); - v = std::move(vars); - } - template void from_variant( const fc::variant& v, fc::static_variant& s ) - { - auto ar = v.get_array(); - if( ar.size() < 2 ) return; - s.set_which( ar[0].as_uint64() ); - s.visit( to_static_variant(ar[1]) ); - } +template struct get_typename { static const char* name() { return BOOST_CORE_TYPEID(std::variant).name(); } }; - template struct get_typename { static const char* name() { return BOOST_CORE_TYPEID(static_variant).name(); } }; -} // namespace fc +} \ No newline at end of file diff --git a/include/fc/variant.hpp b/include/fc/variant.hpp index f261076da..37d6bb20c 100644 --- a/include/fc/variant.hpp +++ b/include/fc/variant.hpp @@ -15,8 +15,8 @@ #include #include #include - #include +#include namespace fc { @@ -40,17 +40,15 @@ namespace fc class time_point_sec; class microseconds; template struct safe; - template - class static_variant; struct blob { std::vector data; }; - void to_variant( const blob& var, variant& vo ); - void from_variant( const variant& var, blob& vo ); + void to_variant( const blob& var, fc::variant& vo ); + void from_variant( const fc::variant& var, blob& vo ); - template void to_variant( const boost::multi_index_container& s, variant& v ); - template void from_variant( const variant& v, boost::multi_index_container& s ); + template void to_variant( const boost::multi_index_container& s, fc::variant& v ); + template void from_variant( const fc::variant& v, boost::multi_index_container& s ); template using UInt = boost::multiprecision::number< @@ -59,80 +57,80 @@ namespace fc using Int = boost::multiprecision::number< boost::multiprecision::cpp_int_backend >; - void to_variant( const UInt<8>& n, variant& v ); - void from_variant( const variant& v, UInt<8>& n ); + void to_variant( const UInt<8>& n, fc::variant& v ); + void from_variant( const fc::variant& v, UInt<8>& n ); - void to_variant( const UInt<16>& n, variant& v ); - void from_variant( const variant& v, UInt<16>& n ); + void to_variant( const UInt<16>& n, fc::variant& v ); + void from_variant( const fc::variant& v, UInt<16>& n ); - void to_variant( const UInt<32>& n, variant& v ); - void from_variant( const variant& v, UInt<32>& n ); + void to_variant( const UInt<32>& n, fc::variant& v ); + void from_variant( const fc::variant& v, UInt<32>& n ); - void to_variant( const UInt<64>& n, variant& v ); - void from_variant( const variant& v, UInt<64>& n ); + void to_variant( const UInt<64>& n, fc::variant& v ); + void from_variant( const fc::variant& v, UInt<64>& n ); - template void to_variant( const boost::multiprecision::number& n, variant& v ); - template void from_variant( const variant& v, boost::multiprecision::number& n ); + template void to_variant( const boost::multiprecision::number& n, fc::variant& v ); + template void from_variant( const fc::variant& v, boost::multiprecision::number& n ); - template void to_variant( const safe& s, variant& v ); - template void from_variant( const variant& v, safe& s ); - template void to_variant( const std::unique_ptr& s, variant& v ); - template void from_variant( const variant& v, std::unique_ptr& s ); + template void to_variant( const safe& s, fc::variant& v ); + template void from_variant( const fc::variant& v, safe& s ); + template void to_variant( const std::unique_ptr& s, fc::variant& v ); + template void from_variant( const fc::variant& v, std::unique_ptr& s ); - template void to_variant( const static_variant& s, variant& v ); - template void from_variant( const variant& v, static_variant& s ); + template void to_variant( const std::variant& s, fc::variant& v ); + template void from_variant( const fc::variant& v, std::variant& s ); - void to_variant( const uint8_t& var, variant& vo ); - void from_variant( const variant& var, uint8_t& vo ); - void to_variant( const int8_t& var, variant& vo ); - void from_variant( const variant& var, int8_t& vo ); + void to_variant( const uint8_t& var, fc::variant& vo ); + void from_variant( const fc::variant& var, uint8_t& vo ); + void to_variant( const int8_t& var, fc::variant& vo ); + void from_variant( const fc::variant& var, int8_t& vo ); - void to_variant( const uint16_t& var, variant& vo ); - void from_variant( const variant& var, uint16_t& vo ); - void to_variant( const int16_t& var, variant& vo ); - void from_variant( const variant& var, int16_t& vo ); + void to_variant( const uint16_t& var, fc::variant& vo ); + void from_variant( const fc::variant& var, uint16_t& vo ); + void to_variant( const int16_t& var, fc::variant& vo ); + void from_variant( const fc::variant& var, int16_t& vo ); - void to_variant( const uint32_t& var, variant& vo ); - void from_variant( const variant& var, uint32_t& vo ); - void to_variant( const int32_t& var, variant& vo ); - void from_variant( const variant& var, int32_t& vo ); + void to_variant( const uint32_t& var, fc::variant& vo ); + void from_variant( const fc::variant& var, uint32_t& vo ); + void to_variant( const int32_t& var, fc::variant& vo ); + void from_variant( const fc::variant& var, int32_t& vo ); - void to_variant( const unsigned __int128& var, variant& vo ); - void from_variant( const variant& var, unsigned __int128& vo ); - void to_variant( const __int128& var, variant& vo ); - void from_variant( const variant& var, __int128& vo ); + void to_variant( const unsigned __int128& var, fc::variant& vo ); + void from_variant( const fc::variant& var, unsigned __int128& vo ); + void to_variant( const __int128& var, fc::variant& vo ); + void from_variant( const fc::variant& var, __int128& vo ); - void to_variant( const variant_object& var, variant& vo ); - void from_variant( const variant& var, variant_object& vo ); - void to_variant( const mutable_variant_object& var, variant& vo ); - void from_variant( const variant& var, mutable_variant_object& vo ); - void to_variant( const std::vector& var, variant& vo ); - void from_variant( const variant& var, std::vector& vo ); + void to_variant( const variant_object& var, fc::variant& vo ); + void from_variant( const fc::variant& var, variant_object& vo ); + void to_variant( const mutable_variant_object& var, fc::variant& vo ); + void from_variant( const fc::variant& var, mutable_variant_object& vo ); + void to_variant( const std::vector& var, fc::variant& vo ); + void from_variant( const fc::variant& var, std::vector& vo ); template - void to_variant( const std::unordered_map& var, variant& vo ); + void to_variant( const std::unordered_map& var, fc::variant& vo ); template - void from_variant( const variant& var, std::unordered_map& vo ); + void from_variant( const fc::variant& var, std::unordered_map& vo ); template - void to_variant( const std::map& var, variant& vo ); + void to_variant( const std::map& var, fc::variant& vo ); template - void from_variant( const variant& var, std::map& vo ); + void from_variant( const fc::variant& var, std::map& vo ); template - void to_variant( const std::multimap& var, variant& vo ); + void to_variant( const std::multimap& var, fc::variant& vo ); template - void from_variant( const variant& var, std::multimap& vo ); + void from_variant( const fc::variant& var, std::multimap& vo ); template - void to_variant( const std::unordered_set& var, variant& vo ); + void to_variant( const std::unordered_set& var, fc::variant& vo ); template - void from_variant( const variant& var, std::unordered_set& vo ); + void from_variant( const fc::variant& var, std::unordered_set& vo ); template - void to_variant( const std::deque& var, variant& vo ); + void to_variant( const std::deque& var, fc::variant& vo ); template - void from_variant( const variant& var, std::deque& vo ); + void from_variant( const fc::variant& var, std::deque& vo ); template void to_variant( const boost::container::deque& d, fc::variant& vo ); @@ -140,43 +138,43 @@ namespace fc void from_variant( const fc::variant& v, boost::container::deque& d ); template - void to_variant( const std::set& var, variant& vo ); + void to_variant( const std::set& var, fc::variant& vo ); template - void from_variant( const variant& var, std::set& vo ); + void from_variant( const fc::variant& var, std::set& vo ); template - void to_variant( const std::array& var, variant& vo ); + void to_variant( const std::array& var, fc::variant& vo ); template - void from_variant( const variant& var, std::array& vo ); + void from_variant( const fc::variant& var, std::array& vo ); - void to_variant( const time_point& var, variant& vo ); - void from_variant( const variant& var, time_point& vo ); + void to_variant( const time_point& var, fc::variant& vo ); + void from_variant( const fc::variant& var, time_point& vo ); - void to_variant( const time_point_sec& var, variant& vo ); - void from_variant( const variant& var, time_point_sec& vo ); + void to_variant( const time_point_sec& var, fc::variant& vo ); + void from_variant( const fc::variant& var, time_point_sec& vo ); - void to_variant( const microseconds& input_microseconds, variant& output_variant ); - void from_variant( const variant& input_variant, microseconds& output_microseconds ); + void to_variant( const microseconds& input_microseconds, fc::variant& output_variant ); + void from_variant( const fc::variant& input_variant, microseconds& output_microseconds ); #ifdef __APPLE__ - void to_variant( size_t s, variant& v ); + void to_variant( size_t s, fc::variant& v ); #elif !defined(_MSC_VER) - void to_variant( long long int s, variant& v ); - void to_variant( unsigned long long int s, variant& v ); + void to_variant( long long int s, fc::variant& v ); + void to_variant( unsigned long long int s, fc::variant& v ); #endif - void to_variant( const std::string& s, variant& v ); + void to_variant( const std::string& s, fc::variant& v ); template - void to_variant( const std::shared_ptr& var, variant& vo ); + void to_variant( const std::shared_ptr& var, fc::variant& vo ); template - void from_variant( const variant& var, std::shared_ptr& vo ); + void from_variant( const fc::variant& var, std::shared_ptr& vo ); - typedef std::vector variants; + typedef std::vector variants; template - void to_variant( const std::pair& t, variant& v ); + void to_variant( const std::pair& t, fc::variant& v ); template - void from_variant( const variant& v, std::pair& p ); + void from_variant( const fc::variant& v, std::pair& p ); @@ -366,27 +364,28 @@ namespace fc double _data; ///< Alligned according to double requirements char _type[sizeof(void*)]; ///< pad to void* size }; + typedef std::optional ovariant; /** @ingroup Serializable */ - void from_variant( const variant& var, string& vo ); + void from_variant( const fc::variant& var, string& vo ); /** @ingroup Serializable */ - void from_variant( const variant& var, variants& vo ); - void from_variant( const variant& var, variant& vo ); + void from_variant( const fc::variant& var, fc::variants& vo ); + void from_variant( const fc::variant& var, fc::variant& vo ); /** @ingroup Serializable */ - void from_variant( const variant& var, int64_t& vo ); + void from_variant( const fc::variant& var, int64_t& vo ); /** @ingroup Serializable */ - void from_variant( const variant& var, uint64_t& vo ); + void from_variant( const fc::variant& var, uint64_t& vo ); /** @ingroup Serializable */ - void from_variant( const variant& var, bool& vo ); + void from_variant( const fc::variant& var, bool& vo ); /** @ingroup Serializable */ - void from_variant( const variant& var, double& vo ); + void from_variant( const fc::variant& var, double& vo ); /** @ingroup Serializable */ - void from_variant( const variant& var, float& vo ); + void from_variant( const fc::variant& var, float& vo ); /** @ingroup Serializable */ - void from_variant( const variant& var, int32_t& vo ); + void from_variant( const fc::variant& var, int32_t& vo ); /** @ingroup Serializable */ - void from_variant( const variant& var, uint32_t& vo ); + void from_variant( const fc::variant& var, uint32_t& vo ); /** @ingroup Serializable */ template void from_variant( const variant& var, std::optional& vo ) @@ -399,17 +398,17 @@ namespace fc } } template - void to_variant( const std::unordered_set& var, variant& vo ) + void to_variant( const std::unordered_set& var, fc::variant& vo ) { if( var.size() > MAX_NUM_ARRAY_ELEMENTS ) throw std::range_error( "too large" ); - std::vector vars(var.size()); + std::vector vars(var.size()); size_t i = 0; for( auto itr = var.begin(); itr != var.end(); ++itr, ++i ) - vars[i] = variant(*itr); + vars[i] = fc::variant(*itr); vo = vars; } template - void from_variant( const variant& var, std::unordered_set& vo ) + void from_variant( const fc::variant& var, std::unordered_set& vo ) { const variants& vars = var.get_array(); if( vars.size() > MAX_NUM_ARRAY_ELEMENTS ) throw std::range_error( "too large" ); @@ -421,17 +420,17 @@ namespace fc template - void to_variant( const std::unordered_map& var, variant& vo ) + void to_variant( const std::unordered_map& var, fc::variant& vo ) { if( var.size() > MAX_NUM_ARRAY_ELEMENTS ) throw std::range_error( "too large" ); - std::vector< variant > vars(var.size()); + std::vector< fc::variant > vars(var.size()); size_t i = 0; for( auto itr = var.begin(); itr != var.end(); ++itr, ++i ) vars[i] = fc::variant(*itr); vo = vars; } template - void from_variant( const variant& var, std::unordered_map& vo ) + void from_variant( const fc::variant& var, std::unordered_map& vo ) { const variants& vars = var.get_array(); if( vars.size() > MAX_NUM_ARRAY_ELEMENTS ) throw std::range_error( "too large" ); @@ -441,17 +440,17 @@ namespace fc } template - void to_variant( const std::map& var, variant& vo ) + void to_variant( const std::map& var, fc::variant& vo ) { if( var.size() > MAX_NUM_ARRAY_ELEMENTS ) throw std::range_error( "too large" ); - std::vector< variant > vars(var.size()); + std::vector< fc::variant > vars(var.size()); size_t i = 0; for( auto itr = var.begin(); itr != var.end(); ++itr, ++i ) vars[i] = fc::variant(*itr); vo = vars; } template - void from_variant( const variant& var, std::map& vo ) + void from_variant( const fc::variant& var, std::map& vo ) { const variants& vars = var.get_array(); if( vars.size() > MAX_NUM_ARRAY_ELEMENTS ) throw std::range_error( "too large" ); @@ -461,17 +460,17 @@ namespace fc } template - void to_variant( const std::multimap& var, variant& vo ) + void to_variant( const std::multimap& var, fc::variant& vo ) { if( var.size() > MAX_NUM_ARRAY_ELEMENTS ) throw std::range_error( "too large" ); - std::vector< variant > vars(var.size()); + std::vector< fc::variant > vars(var.size()); size_t i = 0; for( auto itr = var.begin(); itr != var.end(); ++itr, ++i ) vars[i] = fc::variant(*itr); vo = vars; } template - void from_variant( const variant& var, std::multimap& vo ) + void from_variant( const fc::variant& var, std::multimap& vo ) { const variants& vars = var.get_array(); if( vars.size() > MAX_NUM_ARRAY_ELEMENTS ) throw std::range_error( "too large" ); @@ -482,17 +481,17 @@ namespace fc template - void to_variant( const std::set& var, variant& vo ) + void to_variant( const std::set& var, fc::variant& vo ) { if( var.size() > MAX_NUM_ARRAY_ELEMENTS ) throw std::range_error( "too large" ); - std::vector vars(var.size()); + std::vector vars(var.size()); size_t i = 0; for( auto itr = var.begin(); itr != var.end(); ++itr, ++i ) - vars[i] = variant(*itr); + vars[i] = fc::variant(*itr); vo = vars; } template - void from_variant( const variant& var, std::set& vo ) + void from_variant( const fc::variant& var, std::set& vo ) { const variants& vars = var.get_array(); if( vars.size() > MAX_NUM_ARRAY_ELEMENTS ) throw std::range_error( "too large" ); @@ -504,7 +503,7 @@ namespace fc /** @ingroup Serializable */ template - void from_variant( const variant& var, std::deque& tmp ) + void from_variant( const fc::variant& var, std::deque& tmp ) { const variants& vars = var.get_array(); if( vars.size() > MAX_NUM_ARRAY_ELEMENTS ) throw std::range_error( "too large" ); @@ -515,18 +514,18 @@ namespace fc /** @ingroup Serializable */ template - void to_variant( const std::deque& t, variant& v ) + void to_variant( const std::deque& t, fc::variant& v ) { if( t.size() > MAX_NUM_ARRAY_ELEMENTS ) throw std::range_error( "too large" ); - std::vector vars(t.size()); + std::vector vars(t.size()); for( size_t i = 0; i < t.size(); ++i ) - vars[i] = variant(t[i]); + vars[i] = fc::variant(t[i]); v = std::move(vars); } /** @ingroup Serializable */ template - void from_variant( const variant& v, boost::container::deque& d ) + void from_variant( const fc::variant& v, boost::container::deque& d ) { const variants& vars = v.get_array(); if( vars.size() > MAX_NUM_ARRAY_ELEMENTS ) throw std::range_error( "too large" ); @@ -544,14 +543,14 @@ namespace fc if( d.size() > MAX_NUM_ARRAY_ELEMENTS ) throw std::range_error( "too large" ); variants vars(d.size()); for( size_t i = 0; i < d.size(); ++i ) { - vars[i] = variant( d[i] ); + vars[i] = fc::variant( d[i] ); } vo = std::move( vars ); } /** @ingroup Serializable */ template - void from_variant( const variant& var, std::vector& tmp ) + void from_variant( const fc::variant& var, std::vector& tmp ) { const variants& vars = var.get_array(); if( vars.size() > MAX_NUM_ARRAY_ELEMENTS ) throw std::range_error( "too large" ); @@ -563,18 +562,18 @@ namespace fc /** @ingroup Serializable */ template - void to_variant( const std::vector& t, variant& v ) + void to_variant( const std::vector& t, fc::variant& v ) { if( t.size() > MAX_NUM_ARRAY_ELEMENTS ) throw std::range_error( "too large" ); - std::vector vars(t.size()); + std::vector vars(t.size()); for( size_t i = 0; i < t.size(); ++i ) - vars[i] = variant(t[i]); + vars[i] = fc::variant(t[i]); v = std::move(vars); } /** @ingroup Serializable */ template - void from_variant( const variant& var, std::array& tmp ) + void from_variant( const fc::variant& var, std::array& tmp ) { const variants& vars = var.get_array(); for( std::size_t i = 0; i < S; ++i ) @@ -583,27 +582,27 @@ namespace fc /** @ingroup Serializable */ template - void to_variant( const std::array& t, variant& v ) + void to_variant( const std::array& t, fc::variant& v ) { - std::vector vars(S); + std::vector vars(S); for( std::size_t i = 0; i < S; ++i ) - vars[i] = variant(t[i]); + vars[i] = fc::variant(t[i]); v = std::move(vars); } /** @ingroup Serializable */ template - void to_variant( const std::pair& t, variant& v ) + void to_variant( const std::pair& t, fc::variant& v ) { - std::vector vars(2); - vars[0] = variant(t.first); - vars[1] = variant(t.second); + std::vector vars(2); + vars[0] = fc::variant(t.first); + vars[1] = fc::variant(t.second); v = vars; } /** @ingroup Serializable */ template - void from_variant( const variant& v, std::pair& p ) + void from_variant( const fc::variant& v, std::pair& p ) { const variants& vars = v.get_array(); if( vars.size() > 0 ) @@ -627,17 +626,17 @@ namespace fc } #ifdef __APPLE__ - inline void to_variant( size_t s, variant& v ) { v = variant(uint64_t(s)); } + inline void to_variant( size_t s, fc::variant& v ) { v = fc::variant(uint64_t(s)); } #endif template - void to_variant( const std::shared_ptr& var, variant& vo ) + void to_variant( const std::shared_ptr& var, fc::variant& vo ) { if( var ) to_variant( *var, vo ); else vo = nullptr; } template - void from_variant( const variant& var, std::shared_ptr& vo ) + void from_variant( const fc::variant& var, std::shared_ptr& vo ) { if( var.is_null() ) vo = nullptr; else if( vo ) from_variant( var, *vo ); @@ -647,14 +646,14 @@ namespace fc } } template - void to_variant( const std::unique_ptr& var, variant& vo ) + void to_variant( const std::unique_ptr& var, fc::variant& vo ) { if( var ) to_variant( *var, vo ); else vo = nullptr; } template - void from_variant( const variant& var, std::unique_ptr& vo ) + void from_variant( const fc::variant& var, std::unique_ptr& vo ) { if( var.is_null() ) vo.reset(); else if( vo ) from_variant( var, *vo ); @@ -666,44 +665,44 @@ namespace fc template - void to_variant( const safe& s, variant& v ) { v = s.value; } + void to_variant( const safe& s, fc::variant& v ) { v = s.value; } template - void from_variant( const variant& v, safe& s ) { s.value = v.as_uint64(); } + void from_variant( const fc::variant& v, safe& s ) { s.value = v.as_uint64(); } - template void to_variant( const boost::multi_index_container& c, variant& v ) + template void to_variant( const boost::multi_index_container& c, fc::variant& v ) { - std::vector vars; + std::vector vars; vars.reserve( c.size() ); for( const auto& item : c ) - vars.emplace_back( variant(item) ); + vars.emplace_back( fc::variant(item) ); v = std::move(vars); } - template void from_variant( const variant& v, boost::multi_index_container& c ) + template void from_variant( const fc::variant& v, boost::multi_index_container& c ) { const variants& vars = v.get_array(); c.clear(); for( const auto& item : vars ) c.insert( item.as() ); } - template void to_variant( const boost::multiprecision::number& n, variant& v ) { + template void to_variant( const boost::multiprecision::number& n, fc::variant& v ) { v = n.str(); } - template void from_variant( const variant& v, boost::multiprecision::number& n ) { + template void from_variant( const fc::variant& v, boost::multiprecision::number& n ) { n = boost::multiprecision::number(v.get_string()); } - variant operator + ( const variant& a, const variant& b ); - variant operator - ( const variant& a, const variant& b ); - variant operator * ( const variant& a, const variant& b ); - variant operator / ( const variant& a, const variant& b ); + fc::variant operator + ( const fc::variant& a, const fc::variant& b ); + fc::variant operator - ( const fc::variant& a, const fc::variant& b ); + fc::variant operator * ( const fc::variant& a, const fc::variant& b ); + fc::variant operator / ( const fc::variant& a, const fc::variant& b ); - bool operator == ( const variant& a, const variant& b ); - bool operator != ( const variant& a, const variant& b ); - bool operator < ( const variant& a, const variant& b ); - bool operator > ( const variant& a, const variant& b ); - bool operator ! ( const variant& a ); + bool operator == ( const fc::variant& a, const fc::variant& b ); + bool operator != ( const fc::variant& a, const fc::variant& b ); + bool operator < ( const fc::variant& a, const fc::variant& b ); + bool operator > ( const fc::variant& a, const fc::variant& b ); + bool operator ! ( const fc::variant& a ); } // namespace fc #include diff --git a/src/crypto/private_key.cpp b/src/crypto/private_key.cpp index 2056897df..ba4c06df9 100644 --- a/src/crypto/private_key.cpp +++ b/src/crypto/private_key.cpp @@ -15,7 +15,7 @@ namespace fc { namespace crypto { public_key private_key::get_public_key() const { - return public_key(_storage.visit(public_key_visitor())); + return public_key(std::visit(public_key_visitor(), _storage)); } struct sign_visitor : visitor { @@ -36,7 +36,7 @@ namespace fc { namespace crypto { signature private_key::sign( const sha256& digest, bool require_canonical ) const { - return signature(_storage.visit(sign_visitor(digest, require_canonical))); + return signature(std::visit(sign_visitor(digest, require_canonical), _storage)); } struct generate_shared_secret_visitor : visitor { @@ -48,7 +48,7 @@ namespace fc { namespace crypto { sha512 operator()(const KeyType& key) const { using PublicKeyType = typename KeyType::public_key_type; - return key.generate_shared_secret(_pub_storage.template get()); + return key.generate_shared_secret(std::template get(_pub_storage)); } const public_key::storage_type& _pub_storage; @@ -56,7 +56,7 @@ namespace fc { namespace crypto { sha512 private_key::generate_shared_secret( const public_key& pub ) const { - return _storage.visit(generate_shared_secret_visitor(pub._storage)); + return std::visit(generate_shared_secret_visitor(pub._storage), _storage); } template @@ -94,7 +94,7 @@ namespace fc { namespace crypto { if (pivot == std::string::npos) { // wif import - using default_type = private_key::storage_type::template type_at<0>; + using default_type = std::variant_alternative_t<0, private_key::storage_type>; return private_key::storage_type(from_wif(base58str)); } else { constexpr auto prefix = config::private_key_base_prefix; @@ -113,14 +113,15 @@ namespace fc { namespace crypto { std::string private_key::to_string(const fc::yield_function_t& yield) const { - auto which = _storage.which(); + // auto which = _storage.which(); + auto which = _storage.index(); if (which == 0) { - using default_type = storage_type::template type_at<0>; - return to_wif(_storage.template get(), yield); + using default_type = std::variant_alternative_t<0, private_key::storage_type>; + return to_wif(std::template get(_storage), yield); } - auto data_str = _storage.visit(base58str_visitor(yield)); + auto data_str = std::visit(base58str_visitor(yield), _storage); return std::string(config::private_key_base_prefix) + "_" + data_str; } diff --git a/src/crypto/public_key.cpp b/src/crypto/public_key.cpp index 48983241c..2f95c4fae 100644 --- a/src/crypto/public_key.cpp +++ b/src/crypto/public_key.cpp @@ -20,12 +20,12 @@ namespace fc { namespace crypto { }; public_key::public_key( const signature& c, const sha256& digest, bool check_canonical ) - :_storage(c._storage.visit(recovery_visitor(digest, check_canonical))) + :_storage(std::visit(recovery_visitor(digest, check_canonical), c._storage)) { } int public_key::which() const { - return _storage.which(); + return _storage.index(); } static public_key::storage_type parse_base58(const std::string& base58str) @@ -33,7 +33,7 @@ namespace fc { namespace crypto { constexpr auto legacy_prefix = config::public_key_legacy_prefix; if(prefix_matches(legacy_prefix, base58str) && base58str.find('_') == std::string::npos ) { auto sub_str = base58str.substr(const_strlen(legacy_prefix)); - using default_type = typename public_key::storage_type::template type_at<0>; + using default_type = typename std::variant_alternative_t<0, public_key::storage_type>; //public_key::storage_type::template type_at<0>; using data_type = default_type::data_type; using wrapper = checksummed_data; auto bin = fc::from_base58(sub_str); @@ -69,14 +69,14 @@ namespace fc { namespace crypto { bool public_key::valid()const { - return _storage.visit(is_valid_visitor()); + return std::visit(is_valid_visitor(), _storage); } std::string public_key::to_string(const fc::yield_function_t& yield) const { - auto data_str = _storage.visit(base58str_visitor(yield)); + auto data_str = std::visit(base58str_visitor(yield), _storage); - auto which = _storage.which(); + auto which = _storage.index(); if (which == 0) { return std::string(config::public_key_legacy_prefix) + data_str; } else { diff --git a/src/crypto/signature.cpp b/src/crypto/signature.cpp index 44294fff3..c1533b905 100644 --- a/src/crypto/signature.cpp +++ b/src/crypto/signature.cpp @@ -36,26 +36,26 @@ namespace fc { namespace crypto { {} int signature::which() const { - return _storage.which(); + return _storage.index(); } template struct overloaded : Ts... { using Ts::operator()...; }; template overloaded(Ts...) -> overloaded; size_t signature::variable_size() const { - return _storage.visit(overloaded { + return std::visit(overloaded { [&](const auto& k1r1) { - return 0; + return static_cast(0); }, [&](const webauthn::signature& wa) { - return wa.variable_size(); + return static_cast(wa.variable_size()); } - }); + }, _storage); } std::string signature::to_string(const fc::yield_function_t& yield) const { - auto data_str = _storage.visit(base58str_visitor(yield)); + auto data_str = std::visit(base58str_visitor(yield), _storage); yield(); return std::string(config::signature_base_prefix) + "_" + data_str; } @@ -79,7 +79,7 @@ namespace fc { namespace crypto { } size_t hash_value(const signature& b) { - return b._storage.visit(hash_visitor()); + return std::visit(hash_visitor(), b._storage); } } } // eosio::blockchain diff --git a/src/network/http/http_client.cpp b/src/network/http/http_client.cpp index 0718ef30a..d7b940908 100644 --- a/src/network/http/http_client.cpp +++ b/src/network/http/http_client.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include @@ -38,7 +39,7 @@ class http_client_impl { #ifdef BOOST_ASIO_HAS_LOCAL_SOCKETS using unix_socket_ptr = std::unique_ptr; #endif - using connection = static_variantsecond.visit(check_closed_visitor())) { + if (std::visit(check_closed_visitor(), conn_itr->second)) { _connections.erase(conn_itr); return true; } else { @@ -346,7 +347,7 @@ class http_client_impl { }); // Send the HTTP request to the remote host - error_code ec = conn_iter->second.visit(write_request_visitor(this, req, deadline)); + error_code ec = visit(write_request_visitor(this, req, deadline), conn_iter->second); FC_ASSERT(!ec, "Failed to send request: ${message}", ("message",ec.message())); // This buffer is used for reading and must be persisted @@ -356,7 +357,7 @@ class http_client_impl { http::response res; // Receive the HTTP response - ec = conn_iter->second.visit(read_response_visitor(this, buffer, res, deadline)); + ec = std::visit(read_response_visitor(this, buffer, res, deadline), conn_iter->second); FC_ASSERT(!ec, "Failed to read response: ${message}", ("message",ec.message())); // if the connection can be kept open, keep it open @@ -464,4 +465,4 @@ http_client::~http_client() { } -} \ No newline at end of file +} diff --git a/src/rpc/json_connection.cpp b/src/rpc/json_connection.cpp index bde046a15..2d8529ac7 100644 --- a/src/rpc/json_connection.cpp +++ b/src/rpc/json_connection.cpp @@ -25,7 +25,7 @@ namespace fc { namespace rpc { bool _eof; uint64_t _next_id; - boost::unordered_map::ptr> _awaiting; + boost::unordered_map::ptr> _awaiting; boost::unordered_map _methods; boost::unordered_map _named_param_methods; @@ -34,7 +34,7 @@ namespace fc { namespace rpc { logger _logger; - void send_result( variant id, variant result ) + void send_result( fc::variant id, fc::variant result ) { ilog( "send: {\"id\": ${i}, \"result\": ${r}}", ("i",id)("r",result) ); { @@ -47,7 +47,7 @@ namespace fc { namespace rpc { _out->flush(); } } - void send_error( variant id, fc::exception& e ) + void send_error( fc::variant id, fc::exception& e ) { ilog( "send: {\"id\": ${i}, \"error\":{\"message\": ${what},\"code\":0,\"data\":${data}}}", ("i",id)("what",e.what())("data", e) ); @@ -58,11 +58,11 @@ namespace fc { namespace rpc { *_out << ",\"error\":{\"message\":"; json::to_stream( *_out, fc::string(e.what()) ); *_out <<",\"code\":0,\"data\":"; - json::to_stream( *_out, variant(e)); + json::to_stream( *_out, fc::variant(e)); *_out << "}}\n"; _out->flush(); } - //wlog( "exception: ${except}", ("except", variant(e)) ); + //wlog( "exception: ${except}", ("except", fc::variant(e)) ); } void handle_message( const variant_object& obj ) @@ -80,7 +80,7 @@ namespace fc { namespace rpc { try { auto p = obj.find("params"); - variant result; + fc::variant result; if( p == obj.end() ) { auto pmi = _methods.find(m->value().as_string()); @@ -207,7 +207,7 @@ namespace fc { namespace rpc { fc::string line; while( !_done.canceled() ) { - variant v = json::from_stream(*_in); + fc::variant v = json::from_stream(*_in); ///ilog( "input: ${in}", ("in", v ) ); //wlog( "recv: ${line}", ("line", line) ); _handle_message_future = fc::async([=](){ handle_message(v.get_object()); }, "json_connection handle_message"); @@ -342,10 +342,10 @@ namespace fc { namespace rpc { } - future json_connection::async_call( const fc::string& method, const variants& args ) + future json_connection::async_call( const fc::string& method, const variants& args ) { auto id = my->_next_id++; - my->_awaiting[id] = fc::promise::ptr( new fc::promise("json_connection::async_call") ); + my->_awaiting[id] = fc::promise::ptr( new fc::promise("json_connection::async_call") ); { fc::scoped_lock lock(my->_write_mutex); @@ -368,10 +368,10 @@ namespace fc { namespace rpc { return my->_awaiting[id]; } - future json_connection::async_call( const fc::string& method, const variant& a1 ) + future json_connection::async_call( const fc::string& method, const variant& a1 ) { auto id = my->_next_id++; - my->_awaiting[id] = fc::promise::ptr( new fc::promise("json_connection::async_call") ); + my->_awaiting[id] = fc::promise::ptr( new fc::promise("json_connection::async_call") ); { fc::scoped_lock lock(my->_write_mutex); @@ -386,10 +386,10 @@ namespace fc { namespace rpc { } return my->_awaiting[id]; } - future json_connection::async_call( const fc::string& method, const variant& a1, const variant& a2 ) + future json_connection::async_call( const fc::string& method, const fc::variant& a1, const fc::variant& a2 ) { auto id = my->_next_id++; - my->_awaiting[id] = fc::promise::ptr( new fc::promise("json_connection::async_call") ); + my->_awaiting[id] = fc::promise::ptr( new fc::promise("json_connection::async_call") ); { fc::scoped_lock lock(my->_write_mutex); @@ -406,10 +406,10 @@ namespace fc { namespace rpc { } return my->_awaiting[id]; } - future json_connection::async_call( const fc::string& method, const variant& a1, const variant& a2, const variant& a3 ) + future json_connection::async_call( const fc::string& method, const fc::variant& a1, const fc::variant& a2, const fc::variant& a3 ) { auto id = my->_next_id++; - my->_awaiting[id] = fc::promise::ptr( new fc::promise("json_connection::async_call") ); + my->_awaiting[id] = fc::promise::ptr( new fc::promise("json_connection::async_call") ); { fc::scoped_lock lock(my->_write_mutex); @@ -429,10 +429,10 @@ namespace fc { namespace rpc { return my->_awaiting[id]; } - future json_connection::async_call( const fc::string& method, const variant& a1, const variant& a2, const variant& a3, const variant& a4 ) + future json_connection::async_call( const fc::string& method, const fc::variant& a1, const fc::variant& a2, const fc::variant& a3, const fc::variant& a4 ) { auto id = my->_next_id++; - my->_awaiting[id] = fc::promise::ptr( new fc::promise("json_connection::async_call") ); + my->_awaiting[id] = fc::promise::ptr( new fc::promise("json_connection::async_call") ); { fc::scoped_lock lock(my->_write_mutex); @@ -454,10 +454,10 @@ namespace fc { namespace rpc { return my->_awaiting[id]; } - future json_connection::async_call( const fc::string& method, const variant& a1, const variant& a2, const variant& a3, const variant& a4, const variant& a5 ) + future json_connection::async_call( const fc::string& method, const fc::variant& a1, const fc::variant& a2, const fc::variant& a3, const fc::variant& a4, const fc::variant& a5 ) { auto id = my->_next_id++; - my->_awaiting[id] = fc::promise::ptr( new fc::promise("json_connection::async_call") ); + my->_awaiting[id] = fc::promise::ptr( new fc::promise("json_connection::async_call") ); { fc::scoped_lock lock(my->_write_mutex); @@ -481,10 +481,10 @@ namespace fc { namespace rpc { return my->_awaiting[id]; } - future json_connection::async_call( const fc::string& method, const variant& a1, const variant& a2, const variant& a3, const variant& a4, const variant& a5, const variant& a6 ) + future json_connection::async_call( const fc::string& method, const fc::variant& a1, const fc::variant& a2, const fc::variant& a3, const fc::variant& a4, const fc::variant& a5, const fc::variant& a6 ) { auto id = my->_next_id++; - my->_awaiting[id] = fc::promise::ptr( new fc::promise("json_connection::async_call") ); + my->_awaiting[id] = fc::promise::ptr( new fc::promise("json_connection::async_call") ); { fc::scoped_lock lock(my->_write_mutex); @@ -509,10 +509,10 @@ namespace fc { namespace rpc { } return my->_awaiting[id]; } - future json_connection::async_call( const fc::string& method, const variant& a1, const variant& a2, const variant& a3, const variant& a4, const variant& a5, const variant& a6, const variant& a7 ) + future json_connection::async_call( const fc::string& method, const fc::variant& a1, const fc::variant& a2, const fc::variant& a3, const fc::variant& a4, const fc::variant& a5, const fc::variant& a6, const fc::variant& a7 ) { auto id = my->_next_id++; - my->_awaiting[id] = fc::promise::ptr( new fc::promise("json_connection::async_call") ); + my->_awaiting[id] = fc::promise::ptr( new fc::promise("json_connection::async_call") ); { fc::scoped_lock lock(my->_write_mutex); @@ -539,18 +539,18 @@ namespace fc { namespace rpc { } return my->_awaiting[id]; } - future json_connection::async_call( const fc::string& method, - const variant& a1, - const variant& a2, - const variant& a3, - const variant& a4, - const variant& a5, - const variant& a6, - const variant& a7, - const variant& a8 ) + future json_connection::async_call( const fc::string& method, + const fc::variant& a1, + const fc::variant& a2, + const fc::variant& a3, + const fc::variant& a4, + const fc::variant& a5, + const fc::variant& a6, + const fc::variant& a7, + const fc::variant& a8 ) { auto id = my->_next_id++; - my->_awaiting[id] = fc::promise::ptr( new fc::promise("json_connection::async_call") ); + my->_awaiting[id] = fc::promise::ptr( new fc::promise("json_connection::async_call") ); { fc::scoped_lock lock(my->_write_mutex); @@ -579,19 +579,19 @@ namespace fc { namespace rpc { } return my->_awaiting[id]; } - future json_connection::async_call( const fc::string& method, - const variant& a1, - const variant& a2, - const variant& a3, - const variant& a4, - const variant& a5, - const variant& a6, - const variant& a7, - const variant& a8, - const variant& a9 ) + future json_connection::async_call( const fc::string& method, + const fc::variant& a1, + const fc::variant& a2, + const fc::variant& a3, + const fc::variant& a4, + const fc::variant& a5, + const fc::variant& a6, + const fc::variant& a7, + const fc::variant& a8, + const fc::variant& a9 ) { auto id = my->_next_id++; - my->_awaiting[id] = fc::promise::ptr( new fc::promise("json_connection::async_call") ); + my->_awaiting[id] = fc::promise::ptr( new fc::promise("json_connection::async_call") ); { fc::scoped_lock lock(my->_write_mutex); @@ -622,20 +622,20 @@ namespace fc { namespace rpc { } return my->_awaiting[id]; } - future json_connection::async_call( const fc::string& method, - const variant& a1, - const variant& a2, - const variant& a3, - const variant& a4, - const variant& a5, - const variant& a6, - const variant& a7, - const variant& a8, - const variant& a9, - const variant& a10 ) + future json_connection::async_call( const fc::string& method, + const fc::variant& a1, + const fc::variant& a2, + const fc::variant& a3, + const fc::variant& a4, + const fc::variant& a5, + const fc::variant& a6, + const fc::variant& a7, + const fc::variant& a8, + const fc::variant& a9, + const fc::variant& a10 ) { auto id = my->_next_id++; - my->_awaiting[id] = fc::promise::ptr( new fc::promise("json_connection::async_call") ); + my->_awaiting[id] = fc::promise::ptr( new fc::promise("json_connection::async_call") ); { fc::scoped_lock lock(my->_write_mutex); @@ -669,14 +669,14 @@ namespace fc { namespace rpc { return my->_awaiting[id]; } - future json_connection::async_call( const fc::string& method, mutable_variant_object named_args ) + future json_connection::async_call( const fc::string& method, mutable_variant_object named_args ) { return async_call( method, variant_object( fc::move(named_args) ) ); } - future json_connection::async_call( const fc::string& method, const variant_object& named_args ) + future json_connection::async_call( const fc::string& method, const variant_object& named_args ) { auto id = my->_next_id++; - my->_awaiting[id] = fc::promise::ptr( new fc::promise("json_connection::async_call") ); + my->_awaiting[id] = fc::promise::ptr( new fc::promise("json_connection::async_call") ); fc::scoped_lock lock(my->_write_mutex); { *my->_out << "{\"id\":"; @@ -690,10 +690,10 @@ namespace fc { namespace rpc { } return my->_awaiting[id]; } - future json_connection::async_call( const fc::string& method ) + future json_connection::async_call( const fc::string& method ) { auto id = my->_next_id++; - my->_awaiting[id] = fc::promise::ptr( new fc::promise("json_connection::async_call") ); + my->_awaiting[id] = fc::promise::ptr( new fc::promise("json_connection::async_call") ); fc::scoped_lock lock(my->_write_mutex); { *my->_out << "{\"id\":"; diff --git a/src/rpc/state.cpp b/src/rpc/state.cpp index 49fc79ca9..0bad77f0a 100644 --- a/src/rpc/state.cpp +++ b/src/rpc/state.cpp @@ -45,7 +45,7 @@ void state::handle_reply( const response& response ) request state::start_remote_call( const string& method_name, variants args ) { request request{ _next_id++, method_name, std::move(args) }; - _awaiting[*request.id].reset( new boost::fibers::promise() ); + _awaiting[*request.id].reset( new boost::fibers::promise() ); return request; } variant state::wait_for_response( uint64_t request_id ) diff --git a/test/static_variant/test_static_variant.cpp b/test/static_variant/test_static_variant.cpp index 14bbd6033..e9aa3b6dd 100644 --- a/test/static_variant/test_static_variant.cpp +++ b/test/static_variant/test_static_variant.cpp @@ -64,121 +64,121 @@ BOOST_AUTO_TEST_SUITE(static_variant_test_suite) BOOST_AUTO_TEST_CASE(test_eq) { // ensure that the given comparisons are present IFF the types support it - BOOST_REQUIRE(( !variant_has_op_v > )); - BOOST_REQUIRE(( variant_has_op_v > )); + BOOST_REQUIRE(( !variant_has_op_v > )); + BOOST_REQUIRE(( variant_has_op_v > )); // ensure that given comparisons are present IFF the ALL types support it - BOOST_REQUIRE(( !variant_has_op_v > )); - BOOST_REQUIRE(( variant_has_op_v > )); + BOOST_REQUIRE(( !variant_has_op_v > )); + BOOST_REQUIRE(( variant_has_op_v > )); // ensure the operator returns expected values - BOOST_REQUIRE(( static_variant(full_comparable{1}) == static_variant(full_comparable{1}) )); - BOOST_REQUIRE(( !(static_variant(full_comparable{1}) == static_variant(full_comparable{2})) )); + BOOST_REQUIRE(( std::variant(full_comparable{1}) == std::variant(full_comparable{1}) )); + BOOST_REQUIRE(( !(std::variant(full_comparable{1}) == std::variant(full_comparable{2})) )); // ensure the operator respects binary equivalent but different types - BOOST_REQUIRE(( !(static_variant(full_comparable{1}) == static_variant(eq_only{1})) )); + BOOST_REQUIRE(( !(std::variant(full_comparable{1}) == std::variant(eq_only{1})) )); } BOOST_AUTO_TEST_CASE(test_neq) { // ensure that the given comparisons are present IFF the types support it - BOOST_REQUIRE(( !variant_has_op_v > )); - BOOST_REQUIRE(( variant_has_op_v > )); + BOOST_REQUIRE(( !variant_has_op_v > )); + BOOST_REQUIRE(( variant_has_op_v > )); // ensure that given comparisons are present IFF the ALL types support it - BOOST_REQUIRE(( !variant_has_op_v > )); - BOOST_REQUIRE(( variant_has_op_v > )); + BOOST_REQUIRE(( !variant_has_op_v > )); + BOOST_REQUIRE(( variant_has_op_v > )); // ensure the operator returns expected values - BOOST_REQUIRE(( static_variant(full_comparable{1}) != static_variant(full_comparable{2}) )); - BOOST_REQUIRE(( !(static_variant(full_comparable{1}) != static_variant(full_comparable{1})) )); + BOOST_REQUIRE(( std::variant(full_comparable{1}) != std::variant(full_comparable{2}) )); + BOOST_REQUIRE(( !(std::variant(full_comparable{1}) != std::variant(full_comparable{1})) )); // ensure the operator respects binary equivalent but different types - BOOST_REQUIRE(( static_variant(full_comparable{1}) != static_variant(neq_only{1}) )); + BOOST_REQUIRE(( std::variant(full_comparable{1}) != std::variant(neq_only{1}) )); } BOOST_AUTO_TEST_CASE(test_lt) { // ensure that the given comparisons are present IFF the types support it - BOOST_REQUIRE(( !variant_has_op_v > )); - BOOST_REQUIRE(( variant_has_op_v > )); + BOOST_REQUIRE(( !variant_has_op_v > )); + BOOST_REQUIRE(( variant_has_op_v > )); // ensure that given comparisons are present IFF the ALL types support it - BOOST_REQUIRE(( !variant_has_op_v > )); - BOOST_REQUIRE(( variant_has_op_v > )); + BOOST_REQUIRE(( !variant_has_op_v > )); + BOOST_REQUIRE(( variant_has_op_v > )); // ensure the operator returns expected values - BOOST_REQUIRE(( static_variant(full_comparable{1}) < static_variant(full_comparable{2}) )); - BOOST_REQUIRE(( !(static_variant(full_comparable{1}) < static_variant(full_comparable{1})) )); - BOOST_REQUIRE(( !(static_variant(full_comparable{1}) < static_variant(full_comparable{0})) )); + BOOST_REQUIRE(( std::variant(full_comparable{1}) < std::variant(full_comparable{2}) )); + BOOST_REQUIRE(( !(std::variant(full_comparable{1}) < std::variant(full_comparable{1})) )); + BOOST_REQUIRE(( !(std::variant(full_comparable{1}) < std::variant(full_comparable{0})) )); // ensure the operator respects binary equivalent but different types - BOOST_REQUIRE(( static_variant(full_comparable{1}) < static_variant(lt_only{1}) )); - BOOST_REQUIRE(( !(static_variant(full_comparable{1}) < static_variant(full_comparable{1})) )); - BOOST_REQUIRE(( !(static_variant(lt_only{1}) < static_variant(full_comparable{1})) )); + BOOST_REQUIRE(( std::variant(full_comparable{1}) < std::variant(lt_only{1}) )); + BOOST_REQUIRE(( !(std::variant(full_comparable{1}) < std::variant(full_comparable{1})) )); + BOOST_REQUIRE(( !(std::variant(lt_only{1}) < std::variant(full_comparable{1})) )); } BOOST_AUTO_TEST_CASE(test_lte) { // ensure that the given comparisons are present IFF the types support it - BOOST_REQUIRE(( !variant_has_op_v > )); - BOOST_REQUIRE(( variant_has_op_v > )); + BOOST_REQUIRE(( !variant_has_op_v > )); + BOOST_REQUIRE(( variant_has_op_v > )); // ensure that given comparisons are present IFF the ALL types support it - BOOST_REQUIRE(( !variant_has_op_v > )); - BOOST_REQUIRE(( variant_has_op_v > )); + BOOST_REQUIRE(( !variant_has_op_v > )); + BOOST_REQUIRE(( variant_has_op_v > )); // ensure the operator returns expected values - BOOST_REQUIRE(( static_variant(full_comparable{1}) <= static_variant(full_comparable{2}) )); - BOOST_REQUIRE(( static_variant(full_comparable{1}) <= static_variant(full_comparable{1}) )); - BOOST_REQUIRE(( !(static_variant(full_comparable{1}) <= static_variant(full_comparable{0})) )); + BOOST_REQUIRE(( std::variant(full_comparable{1}) <= std::variant(full_comparable{2}) )); + BOOST_REQUIRE(( std::variant(full_comparable{1}) <= std::variant(full_comparable{1}) )); + BOOST_REQUIRE(( !(std::variant(full_comparable{1}) <= std::variant(full_comparable{0})) )); // ensure the operator respects binary equivalent but different types - BOOST_REQUIRE(( static_variant(full_comparable{1}) <= static_variant(lte_only{1}) )); - BOOST_REQUIRE(( static_variant(full_comparable{1}) <= static_variant(full_comparable{1}) )); - BOOST_REQUIRE(( !(static_variant(lte_only{1}) <= static_variant(full_comparable{1})) )); + BOOST_REQUIRE(( std::variant(full_comparable{1}) <= std::variant(lte_only{1}) )); + BOOST_REQUIRE(( std::variant(full_comparable{1}) <= std::variant(full_comparable{1}) )); + BOOST_REQUIRE(( !(std::variant(lte_only{1}) <= std::variant(full_comparable{1})) )); } BOOST_AUTO_TEST_CASE(test_gt) { // ensure that the given comparisons are present IFF the types support it - BOOST_REQUIRE(( !variant_has_op_v > )); - BOOST_REQUIRE(( variant_has_op_v > )); + BOOST_REQUIRE(( !variant_has_op_v > )); + BOOST_REQUIRE(( variant_has_op_v > )); // ensure that given comparisons are present IFF the ALL types support it - BOOST_REQUIRE(( !variant_has_op_v > )); - BOOST_REQUIRE(( variant_has_op_v > )); + BOOST_REQUIRE(( !variant_has_op_v > )); + BOOST_REQUIRE(( variant_has_op_v > )); // ensure the operator returns expected values - BOOST_REQUIRE(( !(static_variant(full_comparable{1}) > static_variant(full_comparable{2})) )); - BOOST_REQUIRE(( !(static_variant(full_comparable{1}) > static_variant(full_comparable{1})) )); - BOOST_REQUIRE(( static_variant(full_comparable{1}) > static_variant(full_comparable{0}) )); + BOOST_REQUIRE(( !(std::variant(full_comparable{1}) > std::variant(full_comparable{2})) )); + BOOST_REQUIRE(( !(std::variant(full_comparable{1}) > std::variant(full_comparable{1})) )); + BOOST_REQUIRE(( std::variant(full_comparable{1}) > std::variant(full_comparable{0}) )); // ensure the operator respects binary equivalent but different types - BOOST_REQUIRE(( !(static_variant(full_comparable{1}) > static_variant(gt_only{1})) )); - BOOST_REQUIRE(( !(static_variant(full_comparable{1}) > static_variant(full_comparable{1})) )); - BOOST_REQUIRE(( static_variant(gt_only{1}) > static_variant(full_comparable{1}) )); + BOOST_REQUIRE(( !(std::variant(full_comparable{1}) > std::variant(gt_only{1})) )); + BOOST_REQUIRE(( !(std::variant(full_comparable{1}) > std::variant(full_comparable{1})) )); + BOOST_REQUIRE(( std::variant(gt_only{1}) > std::variant(full_comparable{1}) )); } BOOST_AUTO_TEST_CASE(test_gte) { // ensure that the given comparisons are present IFF the types support it - BOOST_REQUIRE(( !variant_has_op_v > )); - BOOST_REQUIRE(( variant_has_op_v > )); + BOOST_REQUIRE(( !variant_has_op_v > )); + BOOST_REQUIRE(( variant_has_op_v > )); // ensure that given comparisons are present IFF the ALL types support it - BOOST_REQUIRE(( !variant_has_op_v > )); - BOOST_REQUIRE(( variant_has_op_v > )); + BOOST_REQUIRE(( !variant_has_op_v > )); + BOOST_REQUIRE(( variant_has_op_v > )); // ensure the operator returns expected values - BOOST_REQUIRE(( !(static_variant(full_comparable{1}) >= static_variant(full_comparable{2})) )); - BOOST_REQUIRE(( static_variant(full_comparable{1}) >= static_variant(full_comparable{1}) )); - BOOST_REQUIRE(( static_variant(full_comparable{1}) >= static_variant(full_comparable{0}) )); + BOOST_REQUIRE(( !(std::variant(full_comparable{1}) >= std::variant(full_comparable{2})) )); + BOOST_REQUIRE(( std::variant(full_comparable{1}) >= std::variant(full_comparable{1}) )); + BOOST_REQUIRE(( std::variant(full_comparable{1}) >= std::variant(full_comparable{0}) )); // ensure the operator respects binary equivalent but different types - BOOST_REQUIRE(( !(static_variant(full_comparable{1}) >= static_variant(gte_only{1})) )); - BOOST_REQUIRE(( static_variant(full_comparable{1}) >= static_variant(full_comparable{1}) )); - BOOST_REQUIRE(( static_variant(gte_only{1}) >= static_variant(full_comparable{1}) )); + BOOST_REQUIRE(( !(std::variant(full_comparable{1}) >= std::variant(gte_only{1})) )); + BOOST_REQUIRE(( std::variant(full_comparable{1}) >= std::variant(full_comparable{1}) )); + BOOST_REQUIRE(( std::variant(gte_only{1}) >= std::variant(full_comparable{1}) )); } enum class selected_op { @@ -203,32 +203,33 @@ BOOST_AUTO_TEST_SUITE(static_variant_test_suite) BOOST_AUTO_TEST_CASE(test_visitor) { test_visitor_type visitor; - using var_type = static_variant>; + using var_type = std::variant>; var_type string_lvalue = string("abcd"); const var_type string_const_value = string("abcd"); - BOOST_CHECK(string_lvalue.visit(visitor) == selected_op::STRING_LVALUE_REF); - BOOST_CHECK(var_type(string("abcd")).visit(visitor) == selected_op::STRING_RVALUE_REF); - BOOST_CHECK(string_const_value.visit(visitor) == selected_op::STRING_CONST_REF); + BOOST_CHECK(std::visit(visitor, string_lvalue) == selected_op::STRING_LVALUE_REF); + BOOST_CHECK(std::visit(visitor, var_type(string("abcd"))) == selected_op::STRING_RVALUE_REF); + BOOST_CHECK(std::visit(visitor, string_const_value) == selected_op::STRING_CONST_REF); var_type vector_lvalue = std::vector{}; const var_type vector_const_value = std::vector{}; - BOOST_CHECK(vector_lvalue.visit(visitor) == selected_op::VECTOR_LVALUE_REF); - BOOST_CHECK(var_type(std::vector{}).visit(visitor) == selected_op::VECTOR_LVALUE_REF); - BOOST_CHECK(vector_const_value.visit(visitor) == selected_op::VECTOR_CONST_REF); + BOOST_CHECK(std::visit(visitor, vector_lvalue) == selected_op::VECTOR_LVALUE_REF); + BOOST_CHECK(std::visit(visitor, var_type(std::vector{})) == selected_op::VECTOR_LVALUE_REF); + BOOST_CHECK(std::visit(visitor, vector_const_value) == selected_op::VECTOR_CONST_REF); } BOOST_AUTO_TEST_CASE(test_get) { test_visitor_type visitor; - using var_type = static_variant>; + using var_type = std::variant>; var_type lvalue(string("abc")); const var_type const_value(string("abc")); - BOOST_CHECK(visitor(lvalue.get()) == selected_op::STRING_LVALUE_REF); - BOOST_CHECK(visitor(const_value.get()) == selected_op::STRING_CONST_REF); - BOOST_CHECK(visitor(var_type(string("abc")).get()) == selected_op::STRING_RVALUE_REF); + BOOST_CHECK(visitor(std::get(lvalue)) == selected_op::STRING_LVALUE_REF); + BOOST_CHECK(visitor(std::get(const_value)) == selected_op::STRING_CONST_REF); + BOOST_CHECK(visitor(std::get(var_type(string("abc")))) == selected_op::STRING_RVALUE_REF); + } BOOST_AUTO_TEST_SUITE_END() From 0b21af569d703a815998a075d2965e2f99eb7e51 Mon Sep 17 00:00:00 2001 From: Timothy Banks Date: Mon, 22 Jun 2020 14:58:39 -0400 Subject: [PATCH 026/124] Added std namespace qualifier on a few methods. --- src/network/http/http_client.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/http/http_client.cpp b/src/network/http/http_client.cpp index d7b940908..4f7c379d6 100644 --- a/src/network/http/http_client.cpp +++ b/src/network/http/http_client.cpp @@ -347,7 +347,7 @@ class http_client_impl { }); // Send the HTTP request to the remote host - error_code ec = visit(write_request_visitor(this, req, deadline), conn_iter->second); + error_code ec = std::visit(write_request_visitor(this, req, deadline), conn_iter->second); FC_ASSERT(!ec, "Failed to send request: ${message}", ("message",ec.message())); // This buffer is used for reading and must be persisted From 4a0652339941a26040095c9a47d766149e7061da Mon Sep 17 00:00:00 2001 From: Timothy Banks Date: Mon, 22 Jun 2020 18:16:25 -0400 Subject: [PATCH 027/124] Remove static variant tests --- test/static_variant/test_static_variant.cpp | 235 -------------------- 1 file changed, 235 deletions(-) delete mode 100644 test/static_variant/test_static_variant.cpp diff --git a/test/static_variant/test_static_variant.cpp b/test/static_variant/test_static_variant.cpp deleted file mode 100644 index e9aa3b6dd..000000000 --- a/test/static_variant/test_static_variant.cpp +++ /dev/null @@ -1,235 +0,0 @@ -#define BOOST_TEST_MODULE static_variant -#include - -#include -#include - -using namespace fc; - -template -struct comparable_type { - - int value; - - template> - bool operator== (const comparable_type& other ) const { - return value == other.value; - } - - template> - bool operator!= (const comparable_type& other ) const { - return value != other.value; - } - - template> - bool operator< (const comparable_type& other ) const { - return value < other.value; - } - - template> - bool operator<= (const comparable_type& other ) const { - return value <= other.value; - } - - template> - bool operator> (const comparable_type& other ) const { - return value > other.value; - } - - template> - bool operator>= (const comparable_type& other ) const { - return value >= other.value; - } -}; - -template class Op, typename Variant> -std::is_convertible, const Variant&, const Variant&>, bool> variant_has_op_test(int); - -template class Op, typename Variant> -std::false_type variant_has_op_test(...); - -template class Op, typename Variant> -constexpr bool variant_has_op_v = decltype(variant_has_op_test(0))::value; - -using not_comparable = comparable_type<>; -using full_comparable = comparable_type; -using eq_only = comparable_type; -using neq_only = comparable_type; -using lt_only = comparable_type; -using lte_only = comparable_type; -using gt_only = comparable_type; -using gte_only = comparable_type; - -BOOST_AUTO_TEST_SUITE(static_variant_test_suite) - BOOST_AUTO_TEST_CASE(test_eq) - { - // ensure that the given comparisons are present IFF the types support it - BOOST_REQUIRE(( !variant_has_op_v > )); - BOOST_REQUIRE(( variant_has_op_v > )); - - // ensure that given comparisons are present IFF the ALL types support it - BOOST_REQUIRE(( !variant_has_op_v > )); - BOOST_REQUIRE(( variant_has_op_v > )); - - // ensure the operator returns expected values - BOOST_REQUIRE(( std::variant(full_comparable{1}) == std::variant(full_comparable{1}) )); - BOOST_REQUIRE(( !(std::variant(full_comparable{1}) == std::variant(full_comparable{2})) )); - - // ensure the operator respects binary equivalent but different types - BOOST_REQUIRE(( !(std::variant(full_comparable{1}) == std::variant(eq_only{1})) )); - } - - BOOST_AUTO_TEST_CASE(test_neq) - { - // ensure that the given comparisons are present IFF the types support it - BOOST_REQUIRE(( !variant_has_op_v > )); - BOOST_REQUIRE(( variant_has_op_v > )); - - // ensure that given comparisons are present IFF the ALL types support it - BOOST_REQUIRE(( !variant_has_op_v > )); - BOOST_REQUIRE(( variant_has_op_v > )); - - // ensure the operator returns expected values - BOOST_REQUIRE(( std::variant(full_comparable{1}) != std::variant(full_comparable{2}) )); - BOOST_REQUIRE(( !(std::variant(full_comparable{1}) != std::variant(full_comparable{1})) )); - - // ensure the operator respects binary equivalent but different types - BOOST_REQUIRE(( std::variant(full_comparable{1}) != std::variant(neq_only{1}) )); - } - - BOOST_AUTO_TEST_CASE(test_lt) - { - // ensure that the given comparisons are present IFF the types support it - BOOST_REQUIRE(( !variant_has_op_v > )); - BOOST_REQUIRE(( variant_has_op_v > )); - - // ensure that given comparisons are present IFF the ALL types support it - BOOST_REQUIRE(( !variant_has_op_v > )); - BOOST_REQUIRE(( variant_has_op_v > )); - - // ensure the operator returns expected values - BOOST_REQUIRE(( std::variant(full_comparable{1}) < std::variant(full_comparable{2}) )); - BOOST_REQUIRE(( !(std::variant(full_comparable{1}) < std::variant(full_comparable{1})) )); - BOOST_REQUIRE(( !(std::variant(full_comparable{1}) < std::variant(full_comparable{0})) )); - - // ensure the operator respects binary equivalent but different types - BOOST_REQUIRE(( std::variant(full_comparable{1}) < std::variant(lt_only{1}) )); - BOOST_REQUIRE(( !(std::variant(full_comparable{1}) < std::variant(full_comparable{1})) )); - BOOST_REQUIRE(( !(std::variant(lt_only{1}) < std::variant(full_comparable{1})) )); - } - - BOOST_AUTO_TEST_CASE(test_lte) - { - // ensure that the given comparisons are present IFF the types support it - BOOST_REQUIRE(( !variant_has_op_v > )); - BOOST_REQUIRE(( variant_has_op_v > )); - - // ensure that given comparisons are present IFF the ALL types support it - BOOST_REQUIRE(( !variant_has_op_v > )); - BOOST_REQUIRE(( variant_has_op_v > )); - - // ensure the operator returns expected values - BOOST_REQUIRE(( std::variant(full_comparable{1}) <= std::variant(full_comparable{2}) )); - BOOST_REQUIRE(( std::variant(full_comparable{1}) <= std::variant(full_comparable{1}) )); - BOOST_REQUIRE(( !(std::variant(full_comparable{1}) <= std::variant(full_comparable{0})) )); - - // ensure the operator respects binary equivalent but different types - BOOST_REQUIRE(( std::variant(full_comparable{1}) <= std::variant(lte_only{1}) )); - BOOST_REQUIRE(( std::variant(full_comparable{1}) <= std::variant(full_comparable{1}) )); - BOOST_REQUIRE(( !(std::variant(lte_only{1}) <= std::variant(full_comparable{1})) )); - } - - BOOST_AUTO_TEST_CASE(test_gt) - { - // ensure that the given comparisons are present IFF the types support it - BOOST_REQUIRE(( !variant_has_op_v > )); - BOOST_REQUIRE(( variant_has_op_v > )); - - // ensure that given comparisons are present IFF the ALL types support it - BOOST_REQUIRE(( !variant_has_op_v > )); - BOOST_REQUIRE(( variant_has_op_v > )); - - // ensure the operator returns expected values - BOOST_REQUIRE(( !(std::variant(full_comparable{1}) > std::variant(full_comparable{2})) )); - BOOST_REQUIRE(( !(std::variant(full_comparable{1}) > std::variant(full_comparable{1})) )); - BOOST_REQUIRE(( std::variant(full_comparable{1}) > std::variant(full_comparable{0}) )); - - // ensure the operator respects binary equivalent but different types - BOOST_REQUIRE(( !(std::variant(full_comparable{1}) > std::variant(gt_only{1})) )); - BOOST_REQUIRE(( !(std::variant(full_comparable{1}) > std::variant(full_comparable{1})) )); - BOOST_REQUIRE(( std::variant(gt_only{1}) > std::variant(full_comparable{1}) )); - } - - BOOST_AUTO_TEST_CASE(test_gte) - { - // ensure that the given comparisons are present IFF the types support it - BOOST_REQUIRE(( !variant_has_op_v > )); - BOOST_REQUIRE(( variant_has_op_v > )); - - // ensure that given comparisons are present IFF the ALL types support it - BOOST_REQUIRE(( !variant_has_op_v > )); - BOOST_REQUIRE(( variant_has_op_v > )); - - // ensure the operator returns expected values - BOOST_REQUIRE(( !(std::variant(full_comparable{1}) >= std::variant(full_comparable{2})) )); - BOOST_REQUIRE(( std::variant(full_comparable{1}) >= std::variant(full_comparable{1}) )); - BOOST_REQUIRE(( std::variant(full_comparable{1}) >= std::variant(full_comparable{0}) )); - - // ensure the operator respects binary equivalent but different types - BOOST_REQUIRE(( !(std::variant(full_comparable{1}) >= std::variant(gte_only{1})) )); - BOOST_REQUIRE(( std::variant(full_comparable{1}) >= std::variant(full_comparable{1}) )); - BOOST_REQUIRE(( std::variant(gte_only{1}) >= std::variant(full_comparable{1}) )); - } - - enum class selected_op { - STRING_LVALUE_REF, - STRING_RVALUE_REF, - STRING_CONST_REF, - VECTOR_LVALUE_REF, - VECTOR_RVALUE_REF, - VECTOR_CONST_REF - }; - - struct test_visitor_type { - selected_op operator()(string&) const { return selected_op::STRING_LVALUE_REF; } - selected_op operator()(string&&) const { return selected_op::STRING_RVALUE_REF; } - selected_op operator()(const string&) const { return selected_op::STRING_CONST_REF; } - - selected_op operator()(std::vector&) const { return selected_op::VECTOR_LVALUE_REF; } - selected_op operator()(std::vector&&) const { return selected_op::VECTOR_RVALUE_REF; } - selected_op operator()(const std::vector&) const { return selected_op::VECTOR_CONST_REF; } - }; - - BOOST_AUTO_TEST_CASE(test_visitor) - { - test_visitor_type visitor; - using var_type = std::variant>; - var_type string_lvalue = string("abcd"); - const var_type string_const_value = string("abcd"); - - BOOST_CHECK(std::visit(visitor, string_lvalue) == selected_op::STRING_LVALUE_REF); - BOOST_CHECK(std::visit(visitor, var_type(string("abcd"))) == selected_op::STRING_RVALUE_REF); - BOOST_CHECK(std::visit(visitor, string_const_value) == selected_op::STRING_CONST_REF); - - var_type vector_lvalue = std::vector{}; - const var_type vector_const_value = std::vector{}; - - BOOST_CHECK(std::visit(visitor, vector_lvalue) == selected_op::VECTOR_LVALUE_REF); - BOOST_CHECK(std::visit(visitor, var_type(std::vector{})) == selected_op::VECTOR_LVALUE_REF); - BOOST_CHECK(std::visit(visitor, vector_const_value) == selected_op::VECTOR_CONST_REF); - } - - BOOST_AUTO_TEST_CASE(test_get) { - test_visitor_type visitor; - - using var_type = std::variant>; - var_type lvalue(string("abc")); - const var_type const_value(string("abc")); - - BOOST_CHECK(visitor(std::get(lvalue)) == selected_op::STRING_LVALUE_REF); - BOOST_CHECK(visitor(std::get(const_value)) == selected_op::STRING_CONST_REF); - BOOST_CHECK(visitor(std::get(var_type(string("abc")))) == selected_op::STRING_RVALUE_REF); - - } - -BOOST_AUTO_TEST_SUITE_END() From 03b409f12e465f345f72ebcc15575ba81ed04ce3 Mon Sep 17 00:00:00 2001 From: Timothy Banks Date: Mon, 22 Jun 2020 18:25:45 -0400 Subject: [PATCH 028/124] Remove static variant test --- test/static_variant/CMakeLists.txt | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 test/static_variant/CMakeLists.txt diff --git a/test/static_variant/CMakeLists.txt b/test/static_variant/CMakeLists.txt deleted file mode 100644 index 4dca5720c..000000000 --- a/test/static_variant/CMakeLists.txt +++ /dev/null @@ -1,4 +0,0 @@ -add_executable( test_static_variant test_static_variant.cpp) -target_link_libraries( test_static_variant fc ) - -add_test(NAME test_static_variant COMMAND libraries/fc/test/static_variant/test_static_variant WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) From f37adfee58a4fc3903214d51ac0e411d557176ec Mon Sep 17 00:00:00 2001 From: Timothy Banks Date: Mon, 22 Jun 2020 18:44:47 -0400 Subject: [PATCH 029/124] Remove static variant test --- test/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 4d6c4bb3e..b9eff5929 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -2,7 +2,6 @@ add_subdirectory( crypto ) add_subdirectory( io ) add_subdirectory( network ) add_subdirectory( scoped_exit ) -add_subdirectory( static_variant ) add_subdirectory( variant ) add_executable( test_base64 test_base64.cpp ) From dc2bd21174bac7bf1105b6bf5d4e8a8a3ec6220b Mon Sep 17 00:00:00 2001 From: Timothy Banks Date: Wed, 24 Jun 2020 19:39:47 -0400 Subject: [PATCH 030/124] Remove json_connection.hpp --- include/fc/rpc/binary_api_connection.hpp | 1 - include/fc/rpc/json_connection.hpp | 315 ---------- src/rpc/json_connection.cpp | 719 ----------------------- 3 files changed, 1035 deletions(-) delete mode 100644 include/fc/rpc/json_connection.hpp delete mode 100644 src/rpc/json_connection.cpp diff --git a/include/fc/rpc/binary_api_connection.hpp b/include/fc/rpc/binary_api_connection.hpp index 81a81d332..4e389f515 100644 --- a/include/fc/rpc/binary_api_connection.hpp +++ b/include/fc/rpc/binary_api_connection.hpp @@ -8,7 +8,6 @@ #include #include #include -//#include namespace fc { class binary_api_connection; diff --git a/include/fc/rpc/json_connection.hpp b/include/fc/rpc/json_connection.hpp deleted file mode 100644 index 67f323a04..000000000 --- a/include/fc/rpc/json_connection.hpp +++ /dev/null @@ -1,315 +0,0 @@ -#pragma once -#include -#include -#include -#include -#include - -namespace fc { namespace rpc { - - namespace detail { class json_connection_impl; } - - /** - * @brief Implements JSON-RPC 2.0 over a set of io streams - * - * Each JSON RPC message is expected to be on its own line, violators - * will be prosecuted to the fullest extent of the law. - */ - class json_connection - { - public: - typedef std::function method; - typedef std::function named_param_method; - - json_connection( fc::buffered_istream_ptr in, fc::buffered_ostream_ptr out ); - ~json_connection(); - - /** - * Starts processing messages from input - */ - future exec(); - - bool is_open(); - void close(); - - void set_on_disconnected_callback(std::function callback); - - logger get_logger()const; - void set_logger( const logger& l ); - - /** - * @name server interface - * - * Adding methods to the interface allows the remote side - * to call them. - */ - ///@{ - void add_method( const fc::string& name, method ); - void add_named_param_method( const fc::string& name, named_param_method ); - void remove_method( const fc::string& name ); - //@} - - /** - * @name client interface - */ - ///@{ - void notice( const fc::string& method ); - void notice( const fc::string& method, const variants& args ); - void notice( const fc::string& method, const variant_object& named_args ); - - /// args will be handled as named params - future async_call( const fc::string& method, - const variant_object& args ); - - future async_call( const fc::string& method, mutable_variant_object args ); - - /// Sending in an array of variants will be handled as positional arguments - future async_call( const fc::string& method, - const variants& args ); - - future async_call( const fc::string& method ); - - future async_call( const fc::string& method, - const fc::variant& a1 ); - - future async_call( const fc::string& method, - const fc::variant& a1, - const fc::variant& a2 ); - - future async_call( const fc::string& method, - const fc::variant& a1, - const fc::variant& a2, - const fc::variant& a3 ); - - future async_call( const fc::string& method, - const fc::variant& a1, - const fc::variant& a2, - const fc::variant& a3, - const fc::variant& a4 ); - - future async_call( const fc::string& method, - const fc::variant& a1, - const fc::variant& a2, - const fc::variant& a3, - const fc::variant& a4, - const fc::variant& a5 ); - - future async_call( const fc::string& method, - const fc::variant& a1, - const fc::variant& a2, - const fc::variant& a3, - const fc::variant& a4, - const fc::variant& a5, - const fc::variant& a6 ); - - future async_call( const fc::string& method, - const fc::variant& a1, - const fc::variant& a2, - const fc::variant& a3, - const fc::variant& a4, - const fc::variant& a5, - const fc::variant& a6, - const fc::variant& a7 - ); - - future async_call( const fc::string& method, - const fc::variant& a1, - const fc::variant& a2, - const fc::variant& a3, - const fc::variant& a4, - const fc::variant& a5, - const fc::variant& a6, - const fc::variant& a7, - const fc::variant& a8 - ); - future async_call( const fc::string& method, - const fc::variant& a1, - const fc::variant& a2, - const fc::variant& a3, - const fc::variant& a4, - const fc::variant& a5, - const fc::variant& a6, - const fc::variant& a7, - const fc::variant& a8, - const fc::variant& a9 - ); - future async_call( const fc::string& method, - const fc::variant& a1, - const fc::variant& a2, - const fc::variant& a3, - const fc::variant& a4, - const fc::variant& a5, - const fc::variant& a6, - const fc::variant& a7, - const fc::variant& a8, - const fc::variant& a9, - const fc::variant& a10 - ); - - template - Result call( const fc::string& method, - const variants& args, - microseconds timeout = microseconds::maximum()) - { - return async_call( method, args ).wait(timeout).as(); - } - - template - Result call( const fc::string& method, - const fc::variant& a1, - const fc::variant& a2, - const fc::variant& a3, - microseconds timeout = microseconds::maximum()) - { - return async_call( method, a1, a2, a3 ).wait(timeout).as(); - } - - template - Result call( const fc::string& method, - const fc::variant& a1, - const fc::variant& a2, - const fc::variant& a3, - const fc::variant& a4, - microseconds timeout = microseconds::maximum()) - { - return async_call( method, a1, a2, a3, a4).wait(timeout).as(); - } - - template - Result call( const fc::string& method, - const fc::variant& a1, - const fc::variant& a2, - const fc::variant& a3, - const fc::variant& a4, - const fc::variant& a5, - microseconds timeout = microseconds::maximum()) - { - return async_call( method, a1, a2, a3, a4, a5).wait(timeout).as(); - } - - template - Result call( const fc::string& method, - const fc::variant& a1, - const fc::variant& a2, - const fc::variant& a3, - const fc::variant& a4, - const fc::variant& a5, - const fc::variant& a6, - microseconds timeout = microseconds::maximum()) - { - return async_call( method, a1, a2, a3, a4, a5, a6).wait(timeout).as(); - } - template - Result call( const fc::string& method, - const fc::variant& a1, - const fc::variant& a2, - const fc::variant& a3, - const fc::variant& a4, - const fc::variant& a5, - const fc::variant& a6, - const fc::variant& a7, - microseconds timeout = microseconds::maximum()) - { - return async_call( method, a1, a2, a3, a4, a5, a6, a7).wait(timeout).as(); - } - - template - Result call( const fc::string& method, - const fc::variant& a1, - const fc::variant& a2, - const fc::variant& a3, - const fc::variant& a4, - const fc::variant& a5, - const fc::variant& a6, - const fc::variant& a7, - const fc::variant& a8, - microseconds timeout = microseconds::maximum()) - { - return async_call( method, a1, a2, a3, a4, a5, a6, a7, a8).wait(timeout).as(); - } - - template - Result call( const fc::string& method, - const fc::variant& a1, - const fc::variant& a2, - const fc::variant& a3, - const fc::variant& a4, - const fc::variant& a5, - const fc::variant& a6, - const fc::variant& a7, - const fc::variant& a8, - const fc::variant& a9, - microseconds timeout = microseconds::maximum()) - { - return async_call( method, a1, a2, a3, a4, a5, a6, a7, a8, a9).wait(timeout).as(); - } - - template - Result call( const fc::string& method, - const fc::variant& a1, - const fc::variant& a2, - const fc::variant& a3, - const fc::variant& a4, - const fc::variant& a5, - const fc::variant& a6, - const fc::variant& a7, - const fc::variant& a8, - const fc::variant& a9, - const fc::variant& a10, - microseconds timeout = microseconds::maximum()) - { - return async_call( method, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10).wait(timeout).as(); - } - - template - Result call( const fc::string& method, - const fc::variant& a1, - const fc::variant& a2, - microseconds timeout = microseconds::maximum()) - { - return async_call( method, a1, a2 ).wait(timeout).as(); - } - - template - Result call( const fc::string& method, - const fc::variant& a1, - microseconds timeout = microseconds::maximum()) - { - return async_call( method, a1 ).wait(timeout).as(); - } - - template - Result call( const fc::string& method, - variant_object a1, - microseconds timeout = microseconds::maximum()) - { - return async_call( method, fc::move(a1) ).wait(timeout).as(); - } - template - Result call( const fc::string& method, - mutable_variant_object a1, - microseconds timeout = microseconds::maximum()) - { - return async_call( method, variant_object( fc::move(a1) ) ).wait(timeout).as(); - } - - - template - Result call( const fc::string& method, microseconds timeout = microseconds::maximum() ) - { - return async_call( method ).wait(timeout).as(); - } - - /// Sending in a variant_object will be issued as named parameters - fc::variant call( const fc::string& method, const variant_object& named_args ); - ///@} - - private: - std::unique_ptr my; - }; - typedef std::shared_ptr json_connection_ptr; - -}} // fc::rpc - - - diff --git a/src/rpc/json_connection.cpp b/src/rpc/json_connection.cpp deleted file mode 100644 index 2d8529ac7..000000000 --- a/src/rpc/json_connection.cpp +++ /dev/null @@ -1,719 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -namespace fc { namespace rpc { - - namespace detail - { - class json_connection_impl - { - public: - json_connection_impl( fc::buffered_istream_ptr&& in, fc::buffered_ostream_ptr&& out ) - :_in(fc::move(in)),_out(fc::move(out)),_eof(false),_next_id(0),_logger("json_connection"){} - - fc::buffered_istream_ptr _in; - fc::buffered_ostream_ptr _out; - - fc::future _done; - fc::future _handle_message_future; - bool _eof; - - uint64_t _next_id; - boost::unordered_map::ptr> _awaiting; - boost::unordered_map _methods; - boost::unordered_map _named_param_methods; - - fc::mutex _write_mutex; - std::function _on_close; - - logger _logger; - - void send_result( fc::variant id, fc::variant result ) - { - ilog( "send: {\"id\": ${i}, \"result\": ${r}}", ("i",id)("r",result) ); - { - fc::scoped_lock lock(_write_mutex); - *_out << "{\"id\":"; - json::to_stream( *_out, id ); - *_out << ",\"result\":"; - json::to_stream( *_out, result); - *_out << "}\n"; - _out->flush(); - } - } - void send_error( fc::variant id, fc::exception& e ) - { - ilog( "send: {\"id\": ${i}, \"error\":{\"message\": ${what},\"code\":0,\"data\":${data}}}", - ("i",id)("what",e.what())("data", e) ); - { - fc::scoped_lock lock(_write_mutex); - *_out << "{\"id\":"; - json::to_stream( *_out, id ); - *_out << ",\"error\":{\"message\":"; - json::to_stream( *_out, fc::string(e.what()) ); - *_out <<",\"code\":0,\"data\":"; - json::to_stream( *_out, fc::variant(e)); - *_out << "}}\n"; - _out->flush(); - } - //wlog( "exception: ${except}", ("except", fc::variant(e)) ); - } - - void handle_message( const variant_object& obj ) - { - wlog( "recv: ${msg}", ("msg", obj) ); - fc::exception_ptr eptr; - try - { - auto m = obj.find("method"); - auto i = obj.find("id"); - if( m != obj.end() ) - { - fc::exception except; - bool exception_caught = false; - try - { - auto p = obj.find("params"); - fc::variant result; - if( p == obj.end() ) - { - auto pmi = _methods.find(m->value().as_string()); - auto nmi = _named_param_methods.find(m->value().as_string()); - if( pmi != _methods.end() ) - { - result = pmi->second( variants() ); - } - else if( nmi != _named_param_methods.end() ) - { - result = nmi->second( variant_object() ); - } - else // invalid method - { - FC_THROW_EXCEPTION( exception, "Invalid Method '${method}'", ("method",m->value().as_string())); - } - } - else if( p->value().is_array() ) - { - auto pmi = _methods.find(m->value().as_string()); - if( pmi != _methods.end() ) - { - result = pmi->second( p->value().get_array() ); - } - else // invalid method / param combo - { - FC_THROW_EXCEPTION( exception, "Invalid method or params '${method}'", - ("method",m->value().as_string())); - } - - } - else if( p->value().is_object() ) - { - auto nmi = _named_param_methods.find(m->value().as_string()); - if( nmi != _named_param_methods.end() ) - { - result = nmi->second( p->value().get_object() ); - } - else // invalid method / param combo? - { - FC_THROW_EXCEPTION( exception, "Invalid method or params '${method}'", - ("method",m->value().as_string())); - } - } - else // invalid params - { - FC_THROW_EXCEPTION( exception, "Invalid Params for method ${method}", - ("method",m->value().as_string())); - } - if( i != obj.end() ) - { - send_result( i->value(), result ); - } - } - catch ( fc::exception& e ) - { - exception_caught = true; - except = e; - } - if( exception_caught && i != obj.end() ) - send_error( i->value(), except ); - else - fc_wlog( _logger, "json rpc exception: ${exception}", ("exception",except) ); - } - else if( i != obj.end() ) //handle any received JSON response - { - uint64_t id = i->value().as_int64(); - auto await = _awaiting.find(id); - if( await != _awaiting.end() ) - { - auto r = obj.find("result"); - auto e = obj.find("error"); - if( r != obj.end() ) //if regular result response - { - await->second->set_value( r->value() ); - } - else if( e != obj.end() ) //if error response - { - fc::exception_ptr eptr; - try - { - auto err = e->value().get_object(); - auto data = err.find( "data" ); - if( data != err.end() ) - { - //wlog( "exception: ${except}", ("except", data->value() ) ); - await->second->set_exception( data->value().as().dynamic_copy_exception() ); - } - else - await->second->set_exception( exception_ptr(new FC_EXCEPTION( exception, "${error}", ("error",e->value()) ) ) ); - } - catch ( fc::exception& e ) - { - elog( "Error parsing exception: ${e}", ("e", e.to_detail_string() ) ); - eptr = e.dynamic_copy_exception(); - } - if( eptr ) await->second->set_exception( eptr ); - } - else // id found without error, result, nor method field - { - fc_wlog( _logger, "no error or result specified in '${message}'", ("message",obj) ); - } - } - } - else // no method nor request id... invalid message - { - - } - } - catch ( fc::exception& e ) // catch all other errors... - { - fc_elog( _logger, "json rpc exception: ${exception}", ("exception",e )); - elog( "json rpc exception: ${exception}", ("exception",e )); - eptr = e.dynamic_copy_exception(); - } - if( eptr ) { close(eptr); } - } - - void read_loop() - { - fc::exception_ptr eptr; - try - { - fc::string line; - while( !_done.canceled() ) - { - fc::variant v = json::from_stream(*_in); - ///ilog( "input: ${in}", ("in", v ) ); - //wlog( "recv: ${line}", ("line", line) ); - _handle_message_future = fc::async([=](){ handle_message(v.get_object()); }, "json_connection handle_message"); - } - } - catch ( eof_exception& eof ) - { - _eof = true; - eptr = eof.dynamic_copy_exception(); - } - catch ( exception& e ) - { - eptr = e.dynamic_copy_exception(); - } - catch ( ... ) - { - eptr = fc::exception_ptr(new FC_EXCEPTION( unhandled_exception, "json connection read error" )); - } - if( eptr ) close( eptr ); - } - - void close( fc::exception_ptr e ) - { - wlog( "close ${reason}", ("reason", e->to_detail_string() ) ); - if( _on_close ) - _on_close(e); - for( auto itr = _awaiting.begin(); itr != _awaiting.end(); ++itr ) - { - itr->second->set_exception( e->dynamic_copy_exception() ); - } - } - }; - }//namespace detail - - json_connection::json_connection( fc::buffered_istream_ptr in, fc::buffered_ostream_ptr out ) - :my( new detail::json_connection_impl(fc::move(in),fc::move(out)) ) - {} - - json_connection::~json_connection() - { - close(); - } - - fc::future json_connection::exec() - { - if( my->_done.valid() ) - { - FC_THROW_EXCEPTION( assert_exception, "start should only be called once" ); - } - return my->_done = fc::async( [=](){ my->read_loop(); }, "json_connection read_loop" ); - } - - void json_connection::close() - { - try - { - if( my->_handle_message_future.valid() && !my->_handle_message_future.ready() ) - my->_handle_message_future.cancel_and_wait(__FUNCTION__); - if( my->_done.valid() && !my->_done.ready() ) - { - my->_done.cancel("json_connection is destructing"); - my->_out->close(); - my->_done.wait(); - } - } - catch ( fc::canceled_exception& ){} // expected exception - catch ( fc::eof_exception& ){} // expected exception - catch ( fc::exception& e ) - { - // unhandled, unexpected exception cannot throw from destructor, so log it. - wlog( "${exception}", ("exception",e.to_detail_string()) ); - } - } - - void json_connection::set_on_disconnected_callback(std::function callback) - { - my->_on_close = callback; - } - - void json_connection::add_method( const fc::string& name, method m ) - { - ilog( "add method ${name}", ("name",name) ); - my->_methods.emplace(std::pair(name,fc::move(m))); - } - void json_connection::add_named_param_method( const fc::string& name, named_param_method m ) - { - ilog( "add named param method ${name}", ("name",name) ); - my->_named_param_methods.emplace(std::pair(name,fc::move(m))); - } - void json_connection::remove_method( const fc::string& name ) - { - my->_methods.erase(name); - my->_named_param_methods.erase(name); - } - void json_connection::notice( const fc::string& method, const variants& args ) - { - fc::scoped_lock lock(my->_write_mutex); - *my->_out << "{\"method\":"; - json::to_stream( *my->_out, method ); - if( args.size() ) - { - *my->_out << ",\"params\":"; - fc::json::to_stream( *my->_out, args ); - *my->_out << "}\n"; - } - else - { - *my->_out << ",\"params\":[]}\n"; - } - } - void json_connection::notice( const fc::string& method, const variant_object& named_args ) - { - { - fc::scoped_lock lock(my->_write_mutex); - *my->_out << "{\"method\":"; - json::to_stream( *my->_out, method ); - *my->_out << ",\"params\":"; - fc::json::to_stream( *my->_out, named_args ); - *my->_out << "}\n"; - my->_out->flush(); - } - } - void json_connection::notice( const fc::string& method ) - { - { - fc::scoped_lock lock(my->_write_mutex); - *my->_out << "{\"method\":"; - json::to_stream( *my->_out, method ); - *my->_out << "}\n"; - my->_out->flush(); - } - } - - - future json_connection::async_call( const fc::string& method, const variants& args ) - { - auto id = my->_next_id++; - my->_awaiting[id] = fc::promise::ptr( new fc::promise("json_connection::async_call") ); - - { - fc::scoped_lock lock(my->_write_mutex); - *my->_out << "{\"id\":"; - *my->_out << id; - *my->_out << ",\"method\":"; - json::to_stream( *my->_out, method ); - if( args.size() ) - { - *my->_out << ",\"params\":"; - fc::json::to_stream( *my->_out, args ); - *my->_out << "}\n"; - } - else - { - *my->_out << ",\"params\":[]}\n"; - } - my->_out->flush(); - } - return my->_awaiting[id]; - } - - future json_connection::async_call( const fc::string& method, const variant& a1 ) - { - auto id = my->_next_id++; - my->_awaiting[id] = fc::promise::ptr( new fc::promise("json_connection::async_call") ); - - { - fc::scoped_lock lock(my->_write_mutex); - *my->_out << "{\"id\":"; - *my->_out << id; - *my->_out << ",\"method\":"; - json::to_stream( *my->_out, method ); - *my->_out << ",\"params\":["; - fc::json::to_stream( *my->_out, a1 ); - *my->_out << "]}\n"; - my->_out->flush(); - } - return my->_awaiting[id]; - } - future json_connection::async_call( const fc::string& method, const fc::variant& a1, const fc::variant& a2 ) - { - auto id = my->_next_id++; - my->_awaiting[id] = fc::promise::ptr( new fc::promise("json_connection::async_call") ); - - { - fc::scoped_lock lock(my->_write_mutex); - *my->_out << "{\"id\":"; - *my->_out << id; - *my->_out << ",\"method\":"; - json::to_stream( *my->_out, method ); - *my->_out << ",\"params\":["; - fc::json::to_stream( *my->_out, a1 ); - *my->_out << ","; - fc::json::to_stream( *my->_out, a2 ); - *my->_out << "]}\n"; - my->_out->flush(); - } - return my->_awaiting[id]; - } - future json_connection::async_call( const fc::string& method, const fc::variant& a1, const fc::variant& a2, const fc::variant& a3 ) - { - auto id = my->_next_id++; - my->_awaiting[id] = fc::promise::ptr( new fc::promise("json_connection::async_call") ); - - { - fc::scoped_lock lock(my->_write_mutex); - *my->_out << "{\"id\":"; - *my->_out << id; - *my->_out << ",\"method\":"; - json::to_stream( *my->_out, method ); - *my->_out << ",\"params\":["; - fc::json::to_stream( *my->_out, a1 ); - *my->_out << ","; - fc::json::to_stream( *my->_out, a2 ); - *my->_out << ","; - fc::json::to_stream( *my->_out, a3 ); - *my->_out << "]}\n"; - my->_out->flush(); - } - return my->_awaiting[id]; - } - - future json_connection::async_call( const fc::string& method, const fc::variant& a1, const fc::variant& a2, const fc::variant& a3, const fc::variant& a4 ) - { - auto id = my->_next_id++; - my->_awaiting[id] = fc::promise::ptr( new fc::promise("json_connection::async_call") ); - - { - fc::scoped_lock lock(my->_write_mutex); - *my->_out << "{\"id\":"; - *my->_out << id; - *my->_out << ",\"method\":"; - json::to_stream( *my->_out, method ); - *my->_out << ",\"params\":["; - fc::json::to_stream( *my->_out, a1 ); - *my->_out << ","; - fc::json::to_stream( *my->_out, a2 ); - *my->_out << ","; - fc::json::to_stream( *my->_out, a3 ); - *my->_out << ","; - fc::json::to_stream( *my->_out, a4 ); - *my->_out << "]}\n"; - my->_out->flush(); - } - return my->_awaiting[id]; - } - - future json_connection::async_call( const fc::string& method, const fc::variant& a1, const fc::variant& a2, const fc::variant& a3, const fc::variant& a4, const fc::variant& a5 ) - { - auto id = my->_next_id++; - my->_awaiting[id] = fc::promise::ptr( new fc::promise("json_connection::async_call") ); - - { - fc::scoped_lock lock(my->_write_mutex); - *my->_out << "{\"id\":"; - *my->_out << id; - *my->_out << ",\"method\":"; - json::to_stream( *my->_out, method ); - *my->_out << ",\"params\":["; - fc::json::to_stream( *my->_out, a1 ); - *my->_out << ","; - fc::json::to_stream( *my->_out, a2 ); - *my->_out << ","; - fc::json::to_stream( *my->_out, a3 ); - *my->_out << ","; - fc::json::to_stream( *my->_out, a4 ); - *my->_out << ","; - fc::json::to_stream( *my->_out, a5 ); - *my->_out << "]}\n"; - my->_out->flush(); - } - return my->_awaiting[id]; - } - - future json_connection::async_call( const fc::string& method, const fc::variant& a1, const fc::variant& a2, const fc::variant& a3, const fc::variant& a4, const fc::variant& a5, const fc::variant& a6 ) - { - auto id = my->_next_id++; - my->_awaiting[id] = fc::promise::ptr( new fc::promise("json_connection::async_call") ); - - { - fc::scoped_lock lock(my->_write_mutex); - *my->_out << "{\"id\":"; - *my->_out << id; - *my->_out << ",\"method\":"; - json::to_stream( *my->_out, method ); - *my->_out << ",\"params\":["; - fc::json::to_stream( *my->_out, a1 ); - *my->_out << ","; - fc::json::to_stream( *my->_out, a2 ); - *my->_out << ","; - fc::json::to_stream( *my->_out, a3 ); - *my->_out << ","; - fc::json::to_stream( *my->_out, a4 ); - *my->_out << ","; - fc::json::to_stream( *my->_out, a5 ); - *my->_out << ","; - fc::json::to_stream( *my->_out, a6 ); - *my->_out << "]}\n"; - my->_out->flush(); - } - return my->_awaiting[id]; - } - future json_connection::async_call( const fc::string& method, const fc::variant& a1, const fc::variant& a2, const fc::variant& a3, const fc::variant& a4, const fc::variant& a5, const fc::variant& a6, const fc::variant& a7 ) - { - auto id = my->_next_id++; - my->_awaiting[id] = fc::promise::ptr( new fc::promise("json_connection::async_call") ); - - { - fc::scoped_lock lock(my->_write_mutex); - *my->_out << "{\"id\":"; - *my->_out << id; - *my->_out << ",\"method\":"; - json::to_stream( *my->_out, method ); - *my->_out << ",\"params\":["; - fc::json::to_stream( *my->_out, a1 ); - *my->_out << ","; - fc::json::to_stream( *my->_out, a2 ); - *my->_out << ","; - fc::json::to_stream( *my->_out, a3 ); - *my->_out << ","; - fc::json::to_stream( *my->_out, a4 ); - *my->_out << ","; - fc::json::to_stream( *my->_out, a5 ); - *my->_out << ","; - fc::json::to_stream( *my->_out, a6 ); - *my->_out << ","; - fc::json::to_stream( *my->_out, a7 ); - *my->_out << "]}\n"; - my->_out->flush(); - } - return my->_awaiting[id]; - } - future json_connection::async_call( const fc::string& method, - const fc::variant& a1, - const fc::variant& a2, - const fc::variant& a3, - const fc::variant& a4, - const fc::variant& a5, - const fc::variant& a6, - const fc::variant& a7, - const fc::variant& a8 ) - { - auto id = my->_next_id++; - my->_awaiting[id] = fc::promise::ptr( new fc::promise("json_connection::async_call") ); - - { - fc::scoped_lock lock(my->_write_mutex); - *my->_out << "{\"id\":"; - *my->_out << id; - *my->_out << ",\"method\":"; - json::to_stream( *my->_out, method ); - *my->_out << ",\"params\":["; - fc::json::to_stream( *my->_out, a1 ); - *my->_out << ","; - fc::json::to_stream( *my->_out, a2 ); - *my->_out << ","; - fc::json::to_stream( *my->_out, a3 ); - *my->_out << ","; - fc::json::to_stream( *my->_out, a4 ); - *my->_out << ","; - fc::json::to_stream( *my->_out, a5 ); - *my->_out << ","; - fc::json::to_stream( *my->_out, a6 ); - *my->_out << ","; - fc::json::to_stream( *my->_out, a7 ); - *my->_out << ","; - fc::json::to_stream( *my->_out, a8 ); - *my->_out << "]}\n"; - my->_out->flush(); - } - return my->_awaiting[id]; - } - future json_connection::async_call( const fc::string& method, - const fc::variant& a1, - const fc::variant& a2, - const fc::variant& a3, - const fc::variant& a4, - const fc::variant& a5, - const fc::variant& a6, - const fc::variant& a7, - const fc::variant& a8, - const fc::variant& a9 ) - { - auto id = my->_next_id++; - my->_awaiting[id] = fc::promise::ptr( new fc::promise("json_connection::async_call") ); - - { - fc::scoped_lock lock(my->_write_mutex); - *my->_out << "{\"id\":"; - *my->_out << id; - *my->_out << ",\"method\":"; - json::to_stream( *my->_out, method ); - *my->_out << ",\"params\":["; - fc::json::to_stream( *my->_out, a1 ); - *my->_out << ","; - fc::json::to_stream( *my->_out, a2 ); - *my->_out << ","; - fc::json::to_stream( *my->_out, a3 ); - *my->_out << ","; - fc::json::to_stream( *my->_out, a4 ); - *my->_out << ","; - fc::json::to_stream( *my->_out, a5 ); - *my->_out << ","; - fc::json::to_stream( *my->_out, a6 ); - *my->_out << ","; - fc::json::to_stream( *my->_out, a7 ); - *my->_out << ","; - fc::json::to_stream( *my->_out, a8 ); - *my->_out << ","; - fc::json::to_stream( *my->_out, a9 ); - *my->_out << "]}\n"; - my->_out->flush(); - } - return my->_awaiting[id]; - } - future json_connection::async_call( const fc::string& method, - const fc::variant& a1, - const fc::variant& a2, - const fc::variant& a3, - const fc::variant& a4, - const fc::variant& a5, - const fc::variant& a6, - const fc::variant& a7, - const fc::variant& a8, - const fc::variant& a9, - const fc::variant& a10 ) - { - auto id = my->_next_id++; - my->_awaiting[id] = fc::promise::ptr( new fc::promise("json_connection::async_call") ); - - { - fc::scoped_lock lock(my->_write_mutex); - *my->_out << "{\"id\":"; - *my->_out << id; - *my->_out << ",\"method\":"; - json::to_stream( *my->_out, method ); - *my->_out << ",\"params\":["; - fc::json::to_stream( *my->_out, a1 ); - *my->_out << ","; - fc::json::to_stream( *my->_out, a2 ); - *my->_out << ","; - fc::json::to_stream( *my->_out, a3 ); - *my->_out << ","; - fc::json::to_stream( *my->_out, a4 ); - *my->_out << ","; - fc::json::to_stream( *my->_out, a5 ); - *my->_out << ","; - fc::json::to_stream( *my->_out, a6 ); - *my->_out << ","; - fc::json::to_stream( *my->_out, a7 ); - *my->_out << ","; - fc::json::to_stream( *my->_out, a8 ); - *my->_out << ","; - fc::json::to_stream( *my->_out, a9 ); - *my->_out << ","; - fc::json::to_stream( *my->_out, a10 ); - *my->_out << "]}\n"; - my->_out->flush(); - } - return my->_awaiting[id]; - } - - future json_connection::async_call( const fc::string& method, mutable_variant_object named_args ) - { - return async_call( method, variant_object( fc::move(named_args) ) ); - } - future json_connection::async_call( const fc::string& method, const variant_object& named_args ) - { - auto id = my->_next_id++; - my->_awaiting[id] = fc::promise::ptr( new fc::promise("json_connection::async_call") ); - fc::scoped_lock lock(my->_write_mutex); - { - *my->_out << "{\"id\":"; - *my->_out << id; - *my->_out << ",\"method\":"; - json::to_stream( *my->_out, method ); - *my->_out << ",\"params\":"; - fc::json::to_stream( *my->_out, named_args ); - *my->_out << "}\n"; - my->_out->flush(); - } - return my->_awaiting[id]; - } - future json_connection::async_call( const fc::string& method ) - { - auto id = my->_next_id++; - my->_awaiting[id] = fc::promise::ptr( new fc::promise("json_connection::async_call") ); - fc::scoped_lock lock(my->_write_mutex); - { - *my->_out << "{\"id\":"; - *my->_out << id; - *my->_out << ",\"method\":"; - json::to_stream( *my->_out, method ); - *my->_out << "}\n"; - my->_out->flush(); - } - return my->_awaiting[id]; - } - - logger json_connection::get_logger()const - { - return my->_logger; - } - - void json_connection::set_logger( const logger& l ) - { - my->_logger = l; - } - -}} From e69f0b4ee4fe7673cf91ba7189e01e783ec7a018 Mon Sep 17 00:00:00 2001 From: Timothy Banks Date: Thu, 25 Jun 2020 12:21:45 -0400 Subject: [PATCH 031/124] Fixup per code review comments. Fixed formatting. Created get_if method that will throw fc exception if variant does not currently hold requested type. Revived the static_variant tests. --- include/fc/crypto/common.hpp | 4 +- include/fc/io/raw.hpp | 4 +- include/fc/rpc/api_connection.hpp | 1 - include/fc/rpc/variant_connection.hpp | 42 ++++++++-------- include/fc/static_variant.hpp | 44 ++++++++++++---- src/crypto/private_key.cpp | 1 - src/crypto/public_key.cpp | 2 +- src/crypto/signature.cpp | 2 +- test/CMakeLists.txt | 1 + test/static_variant/CMakeLists.txt | 4 ++ test/static_variant/test_static_variant.cpp | 56 +++++++++++++++++++++ 11 files changed, 123 insertions(+), 38 deletions(-) create mode 100644 test/static_variant/CMakeLists.txt create mode 100644 test/static_variant/test_static_variant.cpp diff --git a/include/fc/crypto/common.hpp b/include/fc/crypto/common.hpp index bde348efb..2be0f4dc3 100644 --- a/include/fc/crypto/common.hpp +++ b/include/fc/crypto/common.hpp @@ -138,7 +138,7 @@ namespace fc { namespace crypto { }; static bool apply(const variant_type& a, const variant_type& b) { - return a.index() == b.index() && std::visit(visitor(b), a); + return a.index() == b.index() && std::visit(visitor(b), a); } }; @@ -166,7 +166,7 @@ namespace fc { namespace crypto { }; static bool apply(const variant_type& a, const variant_type& b) { - return a.index() < b.index() || (a.index() == b.index() && std::visit(visitor(b), a)); + return a.index() < b.index() || (a.index() == b.index() && std::visit(visitor(b), a)); } }; diff --git a/include/fc/io/raw.hpp b/include/fc/io/raw.hpp index 7f61d8a2e..afab435bc 100644 --- a/include/fc/io/raw.hpp +++ b/include/fc/io/raw.hpp @@ -769,8 +769,8 @@ namespace fc { template void pack( Stream& s, const std::variant& sv ) { - fc::raw::pack( s, unsigned_int(sv.index()) ); - std::visit( pack_static_variant(s), sv ); + fc::raw::pack( s, unsigned_int(sv.index()) ); + std::visit( pack_static_variant(s), sv ); } template void unpack( Stream& s, std::variant& sv ) diff --git a/include/fc/rpc/api_connection.hpp b/include/fc/rpc/api_connection.hpp index 8cd6c94fa..d0ca7c12f 100644 --- a/include/fc/rpc/api_connection.hpp +++ b/include/fc/rpc/api_connection.hpp @@ -7,7 +7,6 @@ #include #include #include -//#include namespace fc { class api_connection; diff --git a/include/fc/rpc/variant_connection.hpp b/include/fc/rpc/variant_connection.hpp index aa73ab717..04d2cdf8d 100644 --- a/include/fc/rpc/variant_connection.hpp +++ b/include/fc/rpc/variant_connection.hpp @@ -54,66 +54,66 @@ namespace fc { namespace rpc { /// args will be handled as named params future async_call( const fc::string& method, - const variant_object& args ); + const variant_object& args ); future async_call( const fc::string& method, mutable_variant_object args ); /// Sending in an array of variants will be handled as positional arguments future async_call( const fc::string& method, - const variants& args ); + const variants& args ); future async_call( const fc::string& method ); future async_call( const fc::string& method, - const fc::variant& a1 ); + const fc::variant& a1 ); future async_call( const fc::string& method, - const fc::variant& a1, - const fc::variant& a2 ); + const fc::variant& a1, + const fc::variant& a2 ); future async_call( const fc::string& method, - const fc::variant& a1, - const fc::variant& a2, - const fc::variant& a3 ); + const fc::variant& a1, + const fc::variant& a2, + const fc::variant& a3 ); template Result call( const fc::string& method, - const fc::variant& a1, - const fc::variant& a2, - const fc::variant& a3, - microseconds timeout = microseconds::maximum()) + const fc::variant& a1, + const fc::variant& a2, + const fc::variant& a3, + microseconds timeout = microseconds::maximum()) { return async_call( method, a1, a2, a3 ).wait(timeout).as(); } template Result call( const fc::string& method, - const fc::variant& a1, - const fc::variant& a2, - microseconds timeout = microseconds::maximum()) + const fc::variant& a1, + const fc::variant& a2, + microseconds timeout = microseconds::maximum()) { return async_call( method, a1, a2 ).wait(timeout).as(); } template Result call( const fc::string& method, - const fc::variant& a1, - microseconds timeout = microseconds::maximum()) + const fc::variant& a1, + microseconds timeout = microseconds::maximum()) { return async_call( method, a1 ).wait(timeout).as(); } template Result call( const fc::string& method, - variant_object a1, - microseconds timeout = microseconds::maximum()) + variant_object a1, + microseconds timeout = microseconds::maximum()) { return async_call( method, fc::move(a1) ).wait(timeout).as(); } template Result call( const fc::string& method, - mutable_variant_object a1, - microseconds timeout = microseconds::maximum()) + mutable_variant_object a1, + microseconds timeout = microseconds::maximum()) { return async_call( method, variant_object( fc::move(a1) ) ).wait(timeout).as(); } diff --git a/include/fc/static_variant.hpp b/include/fc/static_variant.hpp index 0ca24ee57..3d9aef0ae 100644 --- a/include/fc/static_variant.hpp +++ b/include/fc/static_variant.hpp @@ -18,25 +18,46 @@ namespace fc { -// This will go away. template struct visitor {}; -template +template +constexpr T& get_if(std::variant& v) +{ + if (auto result = std::get_if(&v)) + { + return *result; + } + + FC_THROW_EXCEPTION(fc::assert_exception, "variant does not contain a value of type ${t}", ("t",fc::get_typename::name())); +} + +template +constexpr const T& get_if(const std::variant& v) +{ + if (const auto result = std::get_if(&v)) + { + return *result; + } + + FC_THROW_EXCEPTION(fc::assert_exception, "variant does not contain a value of type ${t}", ("t",fc::get_typename::name())); +} + +template void from_index(variant& v, int index) { - if constexpr(I >= std::variant_size_v) + if constexpr(i >= std::variant_size_v) { - throw std::runtime_error{"Variant index " + std::to_string(I + index) + " out of bounds"}; + FC_THROW_EXCEPTION(fc::out_of_range_exception, "Provided index out of range for variant."); } else if (index == 0) { - auto value = variant(std::in_place_index); + auto value = variant(std::in_place_index); v = std::move(value); } else { - from_index(v, index - 1); + from_index(v, index - 1); } } @@ -83,15 +104,20 @@ template void to_variant( const std::variant& s, fc::varian { variants vars(2); vars[0] = s.index(); - visit( from_static_variant(vars[1]), s ); + std::visit( from_static_variant(vars[1]), s ); v = std::move(vars); } + template void from_variant( const fc::variant& v, std::variant& s ) { auto ar = v.get_array(); - if( ar.size() < 2 ) return; + if( ar.size() < 2 ) + { + s = std::variant(); + return; + } from_index(s, ar[0].as_uint64()); - visit( to_static_variant(ar[1]), s ); + std::visit( to_static_variant(ar[1]), s ); } template struct get_typename { static const char* name() { return BOOST_CORE_TYPEID(std::variant).name(); } }; diff --git a/src/crypto/private_key.cpp b/src/crypto/private_key.cpp index ba4c06df9..e6faf3b42 100644 --- a/src/crypto/private_key.cpp +++ b/src/crypto/private_key.cpp @@ -113,7 +113,6 @@ namespace fc { namespace crypto { std::string private_key::to_string(const fc::yield_function_t& yield) const { - // auto which = _storage.which(); auto which = _storage.index(); if (which == 0) { diff --git a/src/crypto/public_key.cpp b/src/crypto/public_key.cpp index 2f95c4fae..622a73cfc 100644 --- a/src/crypto/public_key.cpp +++ b/src/crypto/public_key.cpp @@ -69,7 +69,7 @@ namespace fc { namespace crypto { bool public_key::valid()const { - return std::visit(is_valid_visitor(), _storage); + return std::visit(is_valid_visitor(), _storage); } std::string public_key::to_string(const fc::yield_function_t& yield) const diff --git a/src/crypto/signature.cpp b/src/crypto/signature.cpp index c1533b905..ce5c7acfa 100644 --- a/src/crypto/signature.cpp +++ b/src/crypto/signature.cpp @@ -79,7 +79,7 @@ namespace fc { namespace crypto { } size_t hash_value(const signature& b) { - return std::visit(hash_visitor(), b._storage); + return std::visit(hash_visitor(), b._storage); } } } // eosio::blockchain diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index b9eff5929..4d6c4bb3e 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -2,6 +2,7 @@ add_subdirectory( crypto ) add_subdirectory( io ) add_subdirectory( network ) add_subdirectory( scoped_exit ) +add_subdirectory( static_variant ) add_subdirectory( variant ) add_executable( test_base64 test_base64.cpp ) diff --git a/test/static_variant/CMakeLists.txt b/test/static_variant/CMakeLists.txt new file mode 100644 index 000000000..4dca5720c --- /dev/null +++ b/test/static_variant/CMakeLists.txt @@ -0,0 +1,4 @@ +add_executable( test_static_variant test_static_variant.cpp) +target_link_libraries( test_static_variant fc ) + +add_test(NAME test_static_variant COMMAND libraries/fc/test/static_variant/test_static_variant WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) diff --git a/test/static_variant/test_static_variant.cpp b/test/static_variant/test_static_variant.cpp new file mode 100644 index 000000000..222406a2e --- /dev/null +++ b/test/static_variant/test_static_variant.cpp @@ -0,0 +1,56 @@ +#define BOOST_TEST_MODULE static_variant +#include +#include +#include +#include + +BOOST_AUTO_TEST_SUITE(static_variant_test_suite) + BOOST_AUTO_TEST_CASE(to_from_fc_variant) + { + using variant_type = std::variant; + auto std_variant_1 = variant_type{false}; + auto fc_variant = fc::variant{}; + + fc::to_variant(std_variant_1, fc_variant); + + auto std_variant_2 = variant_type{}; + fc::from_variant(fc_variant, std_variant_2); + + BOOST_REQUIRE(std_variant_1 == std_variant_2); + } + + BOOST_AUTO_TEST_CASE(get_if) + { + using variant_type = std::variant; + + auto v1 = variant_type{"hello world"}; + BOOST_CHECK_EXCEPTION(fc::get_if(v1), fc::assert_exception, [](const auto& e) { return true; }); + auto result1 = fc::get_if(v1); + BOOST_REQUIRE(result1 == std::string{"hello world"}); + + const auto v2 = variant_type{"hello world"}; + BOOST_CHECK_EXCEPTION(fc::get_if(v2), fc::assert_exception, [](const auto& e) { return true; }); + const auto result2 = fc::get_if(v2); + BOOST_REQUIRE(result2 == std::string{"hello world"}); + } + + BOOST_AUTO_TEST_CASE(static_variant_from_index) + { + using variant_type = std::variant; + auto v = variant_type{}; + + BOOST_CHECK_EXCEPTION(fc::from_index(v, 3), fc::out_of_range_exception, [](const auto& e) { return e.code() == fc::out_of_range_exception_code; }); + + fc::from_index(v, 2); + BOOST_REQUIRE(std::string{} == std::get(v)); + } + + BOOST_AUTO_TEST_CASE(static_variant_get_index) + { + using variant_type = std::variant; + BOOST_REQUIRE((fc::get_index() == 0)); + BOOST_REQUIRE((fc::get_index() == 1)); + BOOST_REQUIRE((fc::get_index() == 2)); + BOOST_REQUIRE((fc::get_index() == std::variant_size_v)); // Isn't a type contained in variant. + } +BOOST_AUTO_TEST_SUITE_END() From dc39ad4e9107dcfe13b7f3260cabc89fbae76110 Mon Sep 17 00:00:00 2001 From: Timothy Banks Date: Thu, 25 Jun 2020 14:06:19 -0400 Subject: [PATCH 032/124] Corrected failing test --- test/static_variant/test_static_variant.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/static_variant/test_static_variant.cpp b/test/static_variant/test_static_variant.cpp index 222406a2e..22c23643f 100644 --- a/test/static_variant/test_static_variant.cpp +++ b/test/static_variant/test_static_variant.cpp @@ -23,13 +23,13 @@ BOOST_AUTO_TEST_SUITE(static_variant_test_suite) { using variant_type = std::variant; - auto v1 = variant_type{"hello world"}; - BOOST_CHECK_EXCEPTION(fc::get_if(v1), fc::assert_exception, [](const auto& e) { return true; }); + auto v1 = variant_type{std::string{"hello world"}}; + BOOST_CHECK_EXCEPTION(fc::get_if(v1), fc::assert_exception, [](const auto& e) { return e.code() == fc::assert_exception_code; }); auto result1 = fc::get_if(v1); BOOST_REQUIRE(result1 == std::string{"hello world"}); - const auto v2 = variant_type{"hello world"}; - BOOST_CHECK_EXCEPTION(fc::get_if(v2), fc::assert_exception, [](const auto& e) { return true; }); + const auto v2 = variant_type{std::string{"hello world"}}; + BOOST_CHECK_EXCEPTION(fc::get_if(v2), fc::assert_exception, [](const auto& e) { return e.code() == fc::assert_exception_code;; }); const auto result2 = fc::get_if(v2); BOOST_REQUIRE(result2 == std::string{"hello world"}); } From 51535ae3506ef14e4c90aaf780cdddc28242c315 Mon Sep 17 00:00:00 2001 From: Timothy Banks Date: Thu, 25 Jun 2020 15:39:01 -0400 Subject: [PATCH 033/124] Rename get_if to get. --- include/fc/static_variant.hpp | 4 ++-- test/static_variant/test_static_variant.cpp | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/include/fc/static_variant.hpp b/include/fc/static_variant.hpp index 3d9aef0ae..a1ff06d34 100644 --- a/include/fc/static_variant.hpp +++ b/include/fc/static_variant.hpp @@ -22,7 +22,7 @@ template struct visitor {}; template -constexpr T& get_if(std::variant& v) +constexpr T& get(std::variant& v) { if (auto result = std::get_if(&v)) { @@ -33,7 +33,7 @@ constexpr T& get_if(std::variant& v) } template -constexpr const T& get_if(const std::variant& v) +constexpr const T& get(const std::variant& v) { if (const auto result = std::get_if(&v)) { diff --git a/test/static_variant/test_static_variant.cpp b/test/static_variant/test_static_variant.cpp index 22c23643f..61ca850c2 100644 --- a/test/static_variant/test_static_variant.cpp +++ b/test/static_variant/test_static_variant.cpp @@ -19,18 +19,18 @@ BOOST_AUTO_TEST_SUITE(static_variant_test_suite) BOOST_REQUIRE(std_variant_1 == std_variant_2); } - BOOST_AUTO_TEST_CASE(get_if) + BOOST_AUTO_TEST_CASE(get) { using variant_type = std::variant; auto v1 = variant_type{std::string{"hello world"}}; - BOOST_CHECK_EXCEPTION(fc::get_if(v1), fc::assert_exception, [](const auto& e) { return e.code() == fc::assert_exception_code; }); - auto result1 = fc::get_if(v1); + BOOST_CHECK_EXCEPTION(fc::get(v1), fc::assert_exception, [](const auto& e) { return e.code() == fc::assert_exception_code; }); + auto result1 = fc::get(v1); BOOST_REQUIRE(result1 == std::string{"hello world"}); const auto v2 = variant_type{std::string{"hello world"}}; - BOOST_CHECK_EXCEPTION(fc::get_if(v2), fc::assert_exception, [](const auto& e) { return e.code() == fc::assert_exception_code;; }); - const auto result2 = fc::get_if(v2); + BOOST_CHECK_EXCEPTION(fc::get(v2), fc::assert_exception, [](const auto& e) { return e.code() == fc::assert_exception_code;; }); + const auto result2 = fc::get(v2); BOOST_REQUIRE(result2 == std::string{"hello world"}); } From 1315f4f040e13af7cb9f6bb83dc404cce9afea20 Mon Sep 17 00:00:00 2001 From: Timothy Banks Date: Thu, 25 Jun 2020 17:49:52 -0400 Subject: [PATCH 034/124] Added comment to fc::get methods --- include/fc/static_variant.hpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/include/fc/static_variant.hpp b/include/fc/static_variant.hpp index a1ff06d34..45fcbc0a2 100644 --- a/include/fc/static_variant.hpp +++ b/include/fc/static_variant.hpp @@ -21,6 +21,14 @@ namespace fc { template struct visitor {}; +// fc::get mimics the functionality of std::get with the +// exception that in the case of requesting a type that the +// variant currently doesn't hold, it will raise an fc::assert_exception. +// +// Prefer calling fc::get in cases where you are excepting an fc exception. +// In cases where you explicitly checked that the variant is holding the expected +// type (by invoking std::holds_alternative), prefer calling std::get. +// All other cases, prefer calling std::get. template constexpr T& get(std::variant& v) { @@ -32,6 +40,14 @@ constexpr T& get(std::variant& v) FC_THROW_EXCEPTION(fc::assert_exception, "variant does not contain a value of type ${t}", ("t",fc::get_typename::name())); } +// fc::get mimics the functionality of std::get with the +// exception that in the case of requesting a type that the +// variant currently doesn't hold, it will raise an fc::assert_exception. +// +// Prefer calling fc::get in cases where you are excepting an fc exception. +// In cases where you explicitly checked that the variant is holding the expected +// type (by invoking std::holds_alternative), prefer calling std::get. +// All other cases, prefer calling std::get. template constexpr const T& get(const std::variant& v) { From 5b1e9e13c856cf9cab3be8999f6925a5b1c9c0e3 Mon Sep 17 00:00:00 2001 From: Timothy Banks Date: Thu, 25 Jun 2020 19:12:03 -0400 Subject: [PATCH 035/124] Changed exception raised by get_index. --- include/fc/static_variant.hpp | 2 +- test/static_variant/test_static_variant.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/fc/static_variant.hpp b/include/fc/static_variant.hpp index 45fcbc0a2..8feb8a86b 100644 --- a/include/fc/static_variant.hpp +++ b/include/fc/static_variant.hpp @@ -64,7 +64,7 @@ void from_index(variant& v, int index) { if constexpr(i >= std::variant_size_v) { - FC_THROW_EXCEPTION(fc::out_of_range_exception, "Provided index out of range for variant."); + FC_THROW_EXCEPTION(fc::assert_exception, "Provided index out of range for variant."); } else if (index == 0) { diff --git a/test/static_variant/test_static_variant.cpp b/test/static_variant/test_static_variant.cpp index 61ca850c2..505c2e2b8 100644 --- a/test/static_variant/test_static_variant.cpp +++ b/test/static_variant/test_static_variant.cpp @@ -39,7 +39,7 @@ BOOST_AUTO_TEST_SUITE(static_variant_test_suite) using variant_type = std::variant; auto v = variant_type{}; - BOOST_CHECK_EXCEPTION(fc::from_index(v, 3), fc::out_of_range_exception, [](const auto& e) { return e.code() == fc::out_of_range_exception_code; }); + BOOST_CHECK_EXCEPTION(fc::from_index(v, 3), fc::assert_exception, [](const auto& e) { return e.code() == fc::assert_exception_code; }); fc::from_index(v, 2); BOOST_REQUIRE(std::string{} == std::get(v)); From 5682c99a1e9c15b212346cd832704915c618d1a9 Mon Sep 17 00:00:00 2001 From: Timothy Banks Date: Mon, 29 Jun 2020 10:50:43 -0400 Subject: [PATCH 036/124] Created fc::visit to maintain same exception semantics --- include/fc/io/raw.hpp | 4 ++-- include/fc/static_variant.hpp | 23 +++++++++++++++++++++++ src/crypto/private_key.cpp | 8 ++++---- src/crypto/public_key.cpp | 4 ++-- src/crypto/signature.cpp | 6 +++--- src/network/http/http_client.cpp | 6 +++--- 6 files changed, 37 insertions(+), 14 deletions(-) diff --git a/include/fc/io/raw.hpp b/include/fc/io/raw.hpp index afab435bc..b4c2bc72a 100644 --- a/include/fc/io/raw.hpp +++ b/include/fc/io/raw.hpp @@ -770,7 +770,7 @@ namespace fc { void pack( Stream& s, const std::variant& sv ) { fc::raw::pack( s, unsigned_int(sv.index()) ); - std::visit( pack_static_variant(s), sv ); + fc::visit( pack_static_variant(s), sv ); } template void unpack( Stream& s, std::variant& sv ) @@ -778,7 +778,7 @@ namespace fc { unsigned_int w; fc::raw::unpack( s, w ); fc::from_index(sv, w.value); - std::visit( unpack_static_variant(s), sv ); + fc::visit( unpack_static_variant(s), sv ); } diff --git a/include/fc/static_variant.hpp b/include/fc/static_variant.hpp index 8feb8a86b..da2346314 100644 --- a/include/fc/static_variant.hpp +++ b/include/fc/static_variant.hpp @@ -12,6 +12,7 @@ #pragma once #include #include +#include #include #include #include @@ -59,6 +60,28 @@ constexpr const T& get(const std::variant& v) FC_THROW_EXCEPTION(fc::assert_exception, "variant does not contain a value of type ${t}", ("t",fc::get_typename::name())); } +// fc::visit mimics the functionality of std::visit with the +// exception that in the case of the variant not holding a valur, it will raise an fc::assert_exception. +// +// Prefer calling fc::visit in cases where you are excepting an fc exception. +// All other cases, prefer calling std::visit. +template +decltype(auto) visit(Visitor&& vis, Variants&&... vars) +{ + try + { + return std::visit(std::forward(vis), std::forward(vars)...); + } + catch(const std::bad_variant_access&) + { + FC_THROW_EXCEPTION(fc::assert_exception, "Internal error: static_variant tag is invalid."); + } + catch (...) + { + throw; + } +} + template void from_index(variant& v, int index) { diff --git a/src/crypto/private_key.cpp b/src/crypto/private_key.cpp index e6faf3b42..71c33983d 100644 --- a/src/crypto/private_key.cpp +++ b/src/crypto/private_key.cpp @@ -15,7 +15,7 @@ namespace fc { namespace crypto { public_key private_key::get_public_key() const { - return public_key(std::visit(public_key_visitor(), _storage)); + return public_key(fc::visit(public_key_visitor(), _storage)); } struct sign_visitor : visitor { @@ -36,7 +36,7 @@ namespace fc { namespace crypto { signature private_key::sign( const sha256& digest, bool require_canonical ) const { - return signature(std::visit(sign_visitor(digest, require_canonical), _storage)); + return signature(fc::visit(sign_visitor(digest, require_canonical), _storage)); } struct generate_shared_secret_visitor : visitor { @@ -56,7 +56,7 @@ namespace fc { namespace crypto { sha512 private_key::generate_shared_secret( const public_key& pub ) const { - return std::visit(generate_shared_secret_visitor(pub._storage), _storage); + return fc::visit(generate_shared_secret_visitor(pub._storage), _storage); } template @@ -120,7 +120,7 @@ namespace fc { namespace crypto { return to_wif(std::template get(_storage), yield); } - auto data_str = std::visit(base58str_visitor(yield), _storage); + auto data_str = fc::visit(base58str_visitor(yield), _storage); return std::string(config::private_key_base_prefix) + "_" + data_str; } diff --git a/src/crypto/public_key.cpp b/src/crypto/public_key.cpp index 622a73cfc..f2da9e3d0 100644 --- a/src/crypto/public_key.cpp +++ b/src/crypto/public_key.cpp @@ -69,12 +69,12 @@ namespace fc { namespace crypto { bool public_key::valid()const { - return std::visit(is_valid_visitor(), _storage); + return fc::visit(is_valid_visitor(), _storage); } std::string public_key::to_string(const fc::yield_function_t& yield) const { - auto data_str = std::visit(base58str_visitor(yield), _storage); + auto data_str = fc::visit(base58str_visitor(yield), _storage); auto which = _storage.index(); if (which == 0) { diff --git a/src/crypto/signature.cpp b/src/crypto/signature.cpp index ce5c7acfa..4b24c3b1b 100644 --- a/src/crypto/signature.cpp +++ b/src/crypto/signature.cpp @@ -43,7 +43,7 @@ namespace fc { namespace crypto { template overloaded(Ts...) -> overloaded; size_t signature::variable_size() const { - return std::visit(overloaded { + return fc::visit(overloaded { [&](const auto& k1r1) { return static_cast(0); }, @@ -55,7 +55,7 @@ namespace fc { namespace crypto { std::string signature::to_string(const fc::yield_function_t& yield) const { - auto data_str = std::visit(base58str_visitor(yield), _storage); + auto data_str = fc::visit(base58str_visitor(yield), _storage); yield(); return std::string(config::signature_base_prefix) + "_" + data_str; } @@ -79,7 +79,7 @@ namespace fc { namespace crypto { } size_t hash_value(const signature& b) { - return std::visit(hash_visitor(), b._storage); + return fc::visit(hash_visitor(), b._storage); } } } // eosio::blockchain diff --git a/src/network/http/http_client.cpp b/src/network/http/http_client.cpp index 4f7c379d6..8da0bd1dc 100644 --- a/src/network/http/http_client.cpp +++ b/src/network/http/http_client.cpp @@ -260,7 +260,7 @@ class http_client_impl { }; bool check_closed( const connection_map::iterator& conn_itr ) { - if (std::visit(check_closed_visitor(), conn_itr->second)) { + if (fc::visit(check_closed_visitor(), conn_itr->second)) { _connections.erase(conn_itr); return true; } else { @@ -347,7 +347,7 @@ class http_client_impl { }); // Send the HTTP request to the remote host - error_code ec = std::visit(write_request_visitor(this, req, deadline), conn_iter->second); + error_code ec = fc::visit(write_request_visitor(this, req, deadline), conn_iter->second); FC_ASSERT(!ec, "Failed to send request: ${message}", ("message",ec.message())); // This buffer is used for reading and must be persisted @@ -357,7 +357,7 @@ class http_client_impl { http::response res; // Receive the HTTP response - ec = std::visit(read_response_visitor(this, buffer, res, deadline), conn_iter->second); + ec = fc::visit(read_response_visitor(this, buffer, res, deadline), conn_iter->second); FC_ASSERT(!ec, "Failed to read response: ${message}", ("message",ec.message())); // if the connection can be kept open, keep it open From acc78bff2edd23e595c57b1b739f16a0788c9adf Mon Sep 17 00:00:00 2001 From: Timothy Banks Date: Mon, 29 Jun 2020 15:39:11 -0400 Subject: [PATCH 037/124] Cleanup up documentation --- include/fc/static_variant.hpp | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/include/fc/static_variant.hpp b/include/fc/static_variant.hpp index da2346314..f6ca1aa57 100644 --- a/include/fc/static_variant.hpp +++ b/include/fc/static_variant.hpp @@ -1,14 +1,3 @@ -/** This source adapted from https://github.com/kmicklas/variadic-static_variant - * - * Copyright (C) 2013 Kenneth Micklas - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **/ #pragma once #include #include @@ -61,7 +50,7 @@ constexpr const T& get(const std::variant& v) } // fc::visit mimics the functionality of std::visit with the -// exception that in the case of the variant not holding a valur, it will raise an fc::assert_exception. +// exception that in the case of the variant not holding a value, it will raise an fc::assert_exception. // // Prefer calling fc::visit in cases where you are excepting an fc exception. // All other cases, prefer calling std::visit. @@ -159,6 +148,6 @@ template void from_variant( const fc::variant& v, std::variant struct get_typename { static const char* name() { return BOOST_CORE_TYPEID(std::variant).name(); } }; +template struct get_typename { static const char* name() { return BOOST_CORE_TYPEID(std::variant).name(); } }; } \ No newline at end of file From e2b80db5072c0fbb9ee145fc85274bce8f728c07 Mon Sep 17 00:00:00 2001 From: Timothy Banks Date: Wed, 15 Jul 2020 18:41:03 -0400 Subject: [PATCH 038/124] Change fc::exception to derive from std::exception and handle std::exceptions --- include/fc/exception/exception.hpp | 6 +++-- src/exception.cpp | 10 ++++++++- src/network/ntp.cpp | 4 ++++ src/network/udt_socket.cpp | 10 +++++---- src/rpc/cli.cpp | 4 ++++ src/rpc/http_api.cpp | 33 +++++++++++++++++++++++----- src/rpc/websocket_api.cpp | 35 +++++++++++++++++++++++++----- 7 files changed, 84 insertions(+), 18 deletions(-) diff --git a/include/fc/exception/exception.hpp b/include/fc/exception/exception.hpp index c8565ccdd..3afa1340f 100644 --- a/include/fc/exception/exception.hpp +++ b/include/fc/exception/exception.hpp @@ -54,7 +54,7 @@ namespace fc * @see FC_RETHROW_EXCEPTION * @see FC_RETHROW_EXCEPTIONS */ - class exception + class exception : public std::exception { public: static constexpr fc::microseconds format_time_limit = fc::milliseconds( 10 ); // limit time spent formatting exceptions @@ -83,7 +83,7 @@ namespace fc const char* name()const throw(); int64_t code()const throw(); - virtual const char* what()const throw(); + const char* what()const noexcept override; /** * @return a reference to log messages that have @@ -186,6 +186,8 @@ namespace fc std::exception_ptr get_inner_exception()const; + static std_exception_wrapper from_current_exception(const std::exception& e); + virtual NO_RETURN void dynamic_rethrow_exception()const; virtual std::shared_ptr dynamic_copy_exception()const; private: diff --git a/src/exception.cpp b/src/exception.cpp index b05b8cd98..4fe250bbd 100644 --- a/src/exception.cpp +++ b/src/exception.cpp @@ -118,7 +118,7 @@ namespace fc :my( fc::move(c.my) ){} const char* exception::name()const throw() { return my->_name.c_str(); } - const char* exception::what()const throw() { return my->_what.c_str(); } + const char* exception::what()const noexcept { return my->_what.c_str(); } int64_t exception::code()const throw() { return my->_code; } exception::~exception(){} @@ -332,6 +332,14 @@ namespace fc _inner = {std::move(e)}; } + std_exception_wrapper std_exception_wrapper::from_current_exception(const std::exception& e) + { + return std_exception_wrapper{FC_LOG_MESSAGE( warn, "rethrow ${what}: ", ("what",e.what())), + std::current_exception(), + BOOST_CORE_TYPEID(e).name(), + e.what()}; + } + std::exception_ptr std_exception_wrapper::get_inner_exception()const { return _inner; } NO_RETURN void std_exception_wrapper::dynamic_rethrow_exception()const diff --git a/src/network/ntp.cpp b/src/network/ntp.cpp index 00aeadf87..5f9355d6a 100644 --- a/src/network/ntp.cpp +++ b/src/network/ntp.cpp @@ -105,6 +105,10 @@ namespace fc { elog( "${e}", ("e",e.to_detail_string() ) ); } + catch ( const std::exception& e ) + { + elog( "${e}", ("e",e.what() ) ); + } } } // request_now diff --git a/src/network/udt_socket.cpp b/src/network/udt_socket.cpp index 8a814b346..f2e15730a 100644 --- a/src/network/udt_socket.cpp +++ b/src/network/udt_socket.cpp @@ -159,9 +159,10 @@ namespace fc { { try { close(); - } catch ( const fc::exception& e ) - { + } catch ( const fc::exception& e ) { wlog( "${e}", ("e", e.to_detail_string() ) ); + } catch ( const std::exception& e ) { + wlog( "${e}", ("e", e.what() ) ); } } @@ -337,9 +338,10 @@ namespace fc { { try { close(); - } catch ( const fc::exception& e ) - { + } catch ( const fc::exception& e ) { wlog( "${e}", ("e", e.to_detail_string() ) ); + } catch ( const std::exception& e ) { + wlog( "${e}", ("e", e.what() ) ); } } diff --git a/src/rpc/cli.cpp b/src/rpc/cli.cpp index d3070fb8b..858e89e43 100644 --- a/src/rpc/cli.cpp +++ b/src/rpc/cli.cpp @@ -122,6 +122,10 @@ void cli::run() { std::cout << e.to_detail_string() << "\n"; } + catch ( const std::exception& e ) + { + std::cout << e.what() << "\n"; + } } } diff --git a/src/rpc/http_api.cpp b/src/rpc/http_api.cpp index c9a778687..d20e4528c 100644 --- a/src/rpc/http_api.cpp +++ b/src/rpc/http_api.cpp @@ -86,6 +86,13 @@ void http_api_connection::on_request( const fc::http::request& req, const fc::ht std::string resp_body; http::reply::status_code resp_status; + auto handle_error = [&](const auto& e) + { + resp_status = http::reply::InternalServerError; + resp_body = ""; + wdump((e.to_detail_string())); + }; + try { resp.add_header( "Content-Type", "application/json" ); @@ -96,6 +103,12 @@ void http_api_connection::on_request( const fc::http::request& req, const fc::ht if( var_obj.contains( "method" ) ) { auto call = var.as(); + auto handle_error_inner = [&](const auto& e) + { + resp_body = fc::json::to_string( fc::rpc::response( *call.id, error_object{ 1, e.to_detail_string(), fc::variant(e)} ) ); + resp_status = http::reply::InternalServerError;} + }; + try { auto result = _rpc_state.local_call( call.method, call.params ); @@ -104,8 +117,11 @@ void http_api_connection::on_request( const fc::http::request& req, const fc::ht } catch ( const fc::exception& e ) { - resp_body = fc::json::to_string( fc::rpc::response( *call.id, error_object{ 1, e.to_detail_string(), fc::variant(e)} ) ); - resp_status = http::reply::InternalServerError; + handle_error_inner(e); + } + catch ( const std::exception& e ) + { + handle_error_inner(fc::std_exception_wrapper::from_current_exception(e)); } } else @@ -116,10 +132,13 @@ void http_api_connection::on_request( const fc::http::request& req, const fc::ht } catch ( const fc::exception& e ) { - resp_status = http::reply::InternalServerError; - resp_body = ""; - wdump((e.to_detail_string())); + handle_error(e); } + catch ( const std::exception& e ) + { + handle_error(fc::std_exception_wrapper::from_current_exception(e)); + } + try { resp.set_status( resp_status ); @@ -130,6 +149,10 @@ void http_api_connection::on_request( const fc::http::request& req, const fc::ht { wdump((e.to_detail_string())); } + catch ( const std::exception& e ) + { + wdump((fc::std_exception_wrapper::from_current_exception(e).to_detail_string())); + } return; } diff --git a/src/rpc/websocket_api.cpp b/src/rpc/websocket_api.cpp index 8539fc7cf..ad1cee812 100644 --- a/src/rpc/websocket_api.cpp +++ b/src/rpc/websocket_api.cpp @@ -86,6 +86,13 @@ std::string websocket_api_connection::on_message( bool send_message /* = true */ ) { wdump((message)); + + auto handle_error = [&](const auto& e) + { + wdump((e.to_detail_string())); + return e.to_detail_string(); + }; + try { auto var = fc::json::from_string(message); @@ -94,6 +101,17 @@ std::string websocket_api_connection::on_message( { auto call = var.as(); exception_ptr optexcept; + + auto handle_error_inner = [&](const auto& e) + { + if (!call.id) + { + return nullptr; + } + + return e.dynamic_copy_exception(); + }; + try { auto result = _rpc_state.local_call( call.method, call.params ); @@ -107,11 +125,13 @@ std::string websocket_api_connection::on_message( } catch ( const fc::exception& e ) { - if( call.id ) - { - optexcept = e.dynamic_copy_exception(); - } + optexcept = handle_error_inner(e); } + catch ( const std::exception& e ) + { + optexcept = handle_error_inner(fc::std_exception_wrapper::from_current_exception(e)); + } + if( optexcept ) { auto reply = fc::json::to_string( response( *call.id, error_object{ 1, optexcept->to_detail_string(), fc::variant(*optexcept)} ) ); @@ -129,8 +149,11 @@ std::string websocket_api_connection::on_message( } catch ( const fc::exception& e ) { - wdump((e.to_detail_string())); - return e.to_detail_string(); + return handle_error(e); + } + catch ( const std::exception& e) + { + return handle_error(fc::std_exception_wrapper::from_current_exception(e)); } return string(); } From 1d83107a6cccacd852433d52e73540ea2edbed31 Mon Sep 17 00:00:00 2001 From: Timothy Banks Date: Wed, 15 Jul 2020 19:00:22 -0400 Subject: [PATCH 039/124] Throw std exceptions --- include/fc/static_variant.hpp | 44 ++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/include/fc/static_variant.hpp b/include/fc/static_variant.hpp index f6ca1aa57..30e2ae6a8 100644 --- a/include/fc/static_variant.hpp +++ b/include/fc/static_variant.hpp @@ -22,12 +22,13 @@ struct visitor {}; template constexpr T& get(std::variant& v) { - if (auto result = std::get_if(&v)) - { - return *result; - } + return std::get(v); + //if (auto result = std::get_if(&v)) + //{ + // return *result; + //} - FC_THROW_EXCEPTION(fc::assert_exception, "variant does not contain a value of type ${t}", ("t",fc::get_typename::name())); + //FC_THROW_EXCEPTION(fc::assert_exception, "variant does not contain a value of type ${t}", ("t",fc::get_typename::name())); } // fc::get mimics the functionality of std::get with the @@ -41,12 +42,13 @@ constexpr T& get(std::variant& v) template constexpr const T& get(const std::variant& v) { - if (const auto result = std::get_if(&v)) - { - return *result; - } + return std::get(v); + //if (const auto result = std::get_if(&v)) + //{ + // return *result; + //} - FC_THROW_EXCEPTION(fc::assert_exception, "variant does not contain a value of type ${t}", ("t",fc::get_typename::name())); + //FC_THROW_EXCEPTION(fc::assert_exception, "variant does not contain a value of type ${t}", ("t",fc::get_typename::name())); } // fc::visit mimics the functionality of std::visit with the @@ -57,18 +59,18 @@ constexpr const T& get(const std::variant& v) template decltype(auto) visit(Visitor&& vis, Variants&&... vars) { - try - { + //try + //{ return std::visit(std::forward(vis), std::forward(vars)...); - } - catch(const std::bad_variant_access&) - { - FC_THROW_EXCEPTION(fc::assert_exception, "Internal error: static_variant tag is invalid."); - } - catch (...) - { - throw; - } + //} + //catch(const std::bad_variant_access&) + //{ + // FC_THROW_EXCEPTION(fc::assert_exception, "Internal error: static_variant tag is invalid."); + //} + //catch (...) + //{ + // throw; + //} } template From 382943514d73c0a03e412241db3aa8888036e23e Mon Sep 17 00:00:00 2001 From: Timothy Banks Date: Thu, 16 Jul 2020 11:03:29 -0400 Subject: [PATCH 040/124] Update variant tests --- test/static_variant/test_static_variant.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/static_variant/test_static_variant.cpp b/test/static_variant/test_static_variant.cpp index 505c2e2b8..e248bb2b9 100644 --- a/test/static_variant/test_static_variant.cpp +++ b/test/static_variant/test_static_variant.cpp @@ -24,12 +24,12 @@ BOOST_AUTO_TEST_SUITE(static_variant_test_suite) using variant_type = std::variant; auto v1 = variant_type{std::string{"hello world"}}; - BOOST_CHECK_EXCEPTION(fc::get(v1), fc::assert_exception, [](const auto& e) { return e.code() == fc::assert_exception_code; }); + BOOST_CHECK_EXCEPTION(fc::get(v1), std::bad_variant_access, [](const auto& e) { return true; }); auto result1 = fc::get(v1); BOOST_REQUIRE(result1 == std::string{"hello world"}); const auto v2 = variant_type{std::string{"hello world"}}; - BOOST_CHECK_EXCEPTION(fc::get(v2), fc::assert_exception, [](const auto& e) { return e.code() == fc::assert_exception_code;; }); + BOOST_CHECK_EXCEPTION(fc::get(v2), std::bad_variant_access, [](const auto& e) { return true; }); const auto result2 = fc::get(v2); BOOST_REQUIRE(result2 == std::string{"hello world"}); } From 89547e376ce648cf4030d7a4fb7d1a890fb64bf4 Mon Sep 17 00:00:00 2001 From: Timothy Banks Date: Thu, 16 Jul 2020 12:32:17 -0400 Subject: [PATCH 041/124] Remove fc get/visit --- include/fc/io/raw.hpp | 4 +- include/fc/static_variant.hpp | 62 --------------------- src/crypto/private_key.cpp | 8 +-- src/crypto/public_key.cpp | 4 +- src/crypto/signature.cpp | 6 +- src/exception.cpp | 2 +- src/network/http/http_client.cpp | 6 +- test/static_variant/test_static_variant.cpp | 8 +-- 8 files changed, 19 insertions(+), 81 deletions(-) diff --git a/include/fc/io/raw.hpp b/include/fc/io/raw.hpp index b4c2bc72a..afab435bc 100644 --- a/include/fc/io/raw.hpp +++ b/include/fc/io/raw.hpp @@ -770,7 +770,7 @@ namespace fc { void pack( Stream& s, const std::variant& sv ) { fc::raw::pack( s, unsigned_int(sv.index()) ); - fc::visit( pack_static_variant(s), sv ); + std::visit( pack_static_variant(s), sv ); } template void unpack( Stream& s, std::variant& sv ) @@ -778,7 +778,7 @@ namespace fc { unsigned_int w; fc::raw::unpack( s, w ); fc::from_index(sv, w.value); - fc::visit( unpack_static_variant(s), sv ); + std::visit( unpack_static_variant(s), sv ); } diff --git a/include/fc/static_variant.hpp b/include/fc/static_variant.hpp index 30e2ae6a8..d9731490d 100644 --- a/include/fc/static_variant.hpp +++ b/include/fc/static_variant.hpp @@ -11,68 +11,6 @@ namespace fc { template struct visitor {}; -// fc::get mimics the functionality of std::get with the -// exception that in the case of requesting a type that the -// variant currently doesn't hold, it will raise an fc::assert_exception. -// -// Prefer calling fc::get in cases where you are excepting an fc exception. -// In cases where you explicitly checked that the variant is holding the expected -// type (by invoking std::holds_alternative), prefer calling std::get. -// All other cases, prefer calling std::get. -template -constexpr T& get(std::variant& v) -{ - return std::get(v); - //if (auto result = std::get_if(&v)) - //{ - // return *result; - //} - - //FC_THROW_EXCEPTION(fc::assert_exception, "variant does not contain a value of type ${t}", ("t",fc::get_typename::name())); -} - -// fc::get mimics the functionality of std::get with the -// exception that in the case of requesting a type that the -// variant currently doesn't hold, it will raise an fc::assert_exception. -// -// Prefer calling fc::get in cases where you are excepting an fc exception. -// In cases where you explicitly checked that the variant is holding the expected -// type (by invoking std::holds_alternative), prefer calling std::get. -// All other cases, prefer calling std::get. -template -constexpr const T& get(const std::variant& v) -{ - return std::get(v); - //if (const auto result = std::get_if(&v)) - //{ - // return *result; - //} - - //FC_THROW_EXCEPTION(fc::assert_exception, "variant does not contain a value of type ${t}", ("t",fc::get_typename::name())); -} - -// fc::visit mimics the functionality of std::visit with the -// exception that in the case of the variant not holding a value, it will raise an fc::assert_exception. -// -// Prefer calling fc::visit in cases where you are excepting an fc exception. -// All other cases, prefer calling std::visit. -template -decltype(auto) visit(Visitor&& vis, Variants&&... vars) -{ - //try - //{ - return std::visit(std::forward(vis), std::forward(vars)...); - //} - //catch(const std::bad_variant_access&) - //{ - // FC_THROW_EXCEPTION(fc::assert_exception, "Internal error: static_variant tag is invalid."); - //} - //catch (...) - //{ - // throw; - //} -} - template void from_index(variant& v, int index) { diff --git a/src/crypto/private_key.cpp b/src/crypto/private_key.cpp index 71c33983d..e6faf3b42 100644 --- a/src/crypto/private_key.cpp +++ b/src/crypto/private_key.cpp @@ -15,7 +15,7 @@ namespace fc { namespace crypto { public_key private_key::get_public_key() const { - return public_key(fc::visit(public_key_visitor(), _storage)); + return public_key(std::visit(public_key_visitor(), _storage)); } struct sign_visitor : visitor { @@ -36,7 +36,7 @@ namespace fc { namespace crypto { signature private_key::sign( const sha256& digest, bool require_canonical ) const { - return signature(fc::visit(sign_visitor(digest, require_canonical), _storage)); + return signature(std::visit(sign_visitor(digest, require_canonical), _storage)); } struct generate_shared_secret_visitor : visitor { @@ -56,7 +56,7 @@ namespace fc { namespace crypto { sha512 private_key::generate_shared_secret( const public_key& pub ) const { - return fc::visit(generate_shared_secret_visitor(pub._storage), _storage); + return std::visit(generate_shared_secret_visitor(pub._storage), _storage); } template @@ -120,7 +120,7 @@ namespace fc { namespace crypto { return to_wif(std::template get(_storage), yield); } - auto data_str = fc::visit(base58str_visitor(yield), _storage); + auto data_str = std::visit(base58str_visitor(yield), _storage); return std::string(config::private_key_base_prefix) + "_" + data_str; } diff --git a/src/crypto/public_key.cpp b/src/crypto/public_key.cpp index f2da9e3d0..622a73cfc 100644 --- a/src/crypto/public_key.cpp +++ b/src/crypto/public_key.cpp @@ -69,12 +69,12 @@ namespace fc { namespace crypto { bool public_key::valid()const { - return fc::visit(is_valid_visitor(), _storage); + return std::visit(is_valid_visitor(), _storage); } std::string public_key::to_string(const fc::yield_function_t& yield) const { - auto data_str = fc::visit(base58str_visitor(yield), _storage); + auto data_str = std::visit(base58str_visitor(yield), _storage); auto which = _storage.index(); if (which == 0) { diff --git a/src/crypto/signature.cpp b/src/crypto/signature.cpp index 4b24c3b1b..ce5c7acfa 100644 --- a/src/crypto/signature.cpp +++ b/src/crypto/signature.cpp @@ -43,7 +43,7 @@ namespace fc { namespace crypto { template overloaded(Ts...) -> overloaded; size_t signature::variable_size() const { - return fc::visit(overloaded { + return std::visit(overloaded { [&](const auto& k1r1) { return static_cast(0); }, @@ -55,7 +55,7 @@ namespace fc { namespace crypto { std::string signature::to_string(const fc::yield_function_t& yield) const { - auto data_str = fc::visit(base58str_visitor(yield), _storage); + auto data_str = std::visit(base58str_visitor(yield), _storage); yield(); return std::string(config::signature_base_prefix) + "_" + data_str; } @@ -79,7 +79,7 @@ namespace fc { namespace crypto { } size_t hash_value(const signature& b) { - return fc::visit(hash_visitor(), b._storage); + return std::visit(hash_visitor(), b._storage); } } } // eosio::blockchain diff --git a/src/exception.cpp b/src/exception.cpp index 4fe250bbd..a9d9de221 100644 --- a/src/exception.cpp +++ b/src/exception.cpp @@ -334,7 +334,7 @@ namespace fc std_exception_wrapper std_exception_wrapper::from_current_exception(const std::exception& e) { - return std_exception_wrapper{FC_LOG_MESSAGE( warn, "rethrow ${what}: ", ("what",e.what())), + return std_exception_wrapper{FC_LOG_MESSAGE(warn, "rethrow ${what}: ", ("what",e.what())), std::current_exception(), BOOST_CORE_TYPEID(e).name(), e.what()}; diff --git a/src/network/http/http_client.cpp b/src/network/http/http_client.cpp index 8da0bd1dc..4f7c379d6 100644 --- a/src/network/http/http_client.cpp +++ b/src/network/http/http_client.cpp @@ -260,7 +260,7 @@ class http_client_impl { }; bool check_closed( const connection_map::iterator& conn_itr ) { - if (fc::visit(check_closed_visitor(), conn_itr->second)) { + if (std::visit(check_closed_visitor(), conn_itr->second)) { _connections.erase(conn_itr); return true; } else { @@ -347,7 +347,7 @@ class http_client_impl { }); // Send the HTTP request to the remote host - error_code ec = fc::visit(write_request_visitor(this, req, deadline), conn_iter->second); + error_code ec = std::visit(write_request_visitor(this, req, deadline), conn_iter->second); FC_ASSERT(!ec, "Failed to send request: ${message}", ("message",ec.message())); // This buffer is used for reading and must be persisted @@ -357,7 +357,7 @@ class http_client_impl { http::response res; // Receive the HTTP response - ec = fc::visit(read_response_visitor(this, buffer, res, deadline), conn_iter->second); + ec = std::visit(read_response_visitor(this, buffer, res, deadline), conn_iter->second); FC_ASSERT(!ec, "Failed to read response: ${message}", ("message",ec.message())); // if the connection can be kept open, keep it open diff --git a/test/static_variant/test_static_variant.cpp b/test/static_variant/test_static_variant.cpp index e248bb2b9..77cbaa7dd 100644 --- a/test/static_variant/test_static_variant.cpp +++ b/test/static_variant/test_static_variant.cpp @@ -24,13 +24,13 @@ BOOST_AUTO_TEST_SUITE(static_variant_test_suite) using variant_type = std::variant; auto v1 = variant_type{std::string{"hello world"}}; - BOOST_CHECK_EXCEPTION(fc::get(v1), std::bad_variant_access, [](const auto& e) { return true; }); - auto result1 = fc::get(v1); + BOOST_CHECK_EXCEPTION(std::get(v1), std::bad_variant_access, [](const auto& e) { return true; }); + auto result1 = std::get(v1); BOOST_REQUIRE(result1 == std::string{"hello world"}); const auto v2 = variant_type{std::string{"hello world"}}; - BOOST_CHECK_EXCEPTION(fc::get(v2), std::bad_variant_access, [](const auto& e) { return true; }); - const auto result2 = fc::get(v2); + BOOST_CHECK_EXCEPTION(std::get(v2), std::bad_variant_access, [](const auto& e) { return true; }); + const auto result2 = std::get(v2); BOOST_REQUIRE(result2 == std::string{"hello world"}); } From 5493ab9347179753e99991b5de97347fd1e54462 Mon Sep 17 00:00:00 2001 From: Timothy Banks Date: Tue, 21 Jul 2020 14:33:52 -0400 Subject: [PATCH 042/124] Explicitly catch bad_alloc exceptions --- src/network/ntp.cpp | 8 ++++++++ src/network/udt_socket.cpp | 8 ++++++++ src/rpc/cli.cpp | 8 ++++++++ src/rpc/http_api.cpp | 24 ++++++++++++++++++++++++ src/rpc/websocket_api.cpp | 16 ++++++++++++++++ 5 files changed, 64 insertions(+) diff --git a/src/network/ntp.cpp b/src/network/ntp.cpp index 5f9355d6a..c73880278 100644 --- a/src/network/ntp.cpp +++ b/src/network/ntp.cpp @@ -100,6 +100,14 @@ namespace fc { throw; } + catch ( const std::bad_alloc& ) + { + throw; + } + catch ( const boost::interprocess::bad_alloc& ) + { + throw; + } // this could fail to resolve but we want to go on to other hosts.. catch ( const fc::exception& e ) { diff --git a/src/network/udt_socket.cpp b/src/network/udt_socket.cpp index f2e15730a..3806ee787 100644 --- a/src/network/udt_socket.cpp +++ b/src/network/udt_socket.cpp @@ -159,6 +159,10 @@ namespace fc { { try { close(); + } catch ( const std::bad_alloc& ) { + throw; + } catch ( const boost::interprocess::bad_alloc& ) { + throw; } catch ( const fc::exception& e ) { wlog( "${e}", ("e", e.to_detail_string() ) ); } catch ( const std::exception& e ) { @@ -338,6 +342,10 @@ namespace fc { { try { close(); + } catch ( const std::bad_alloc& ) { + throw; + } catch ( const boost::interprocess::bad_alloc& ) { + throw; } catch ( const fc::exception& e ) { wlog( "${e}", ("e", e.to_detail_string() ) ); } catch ( const std::exception& e ) { diff --git a/src/rpc/cli.cpp b/src/rpc/cli.cpp index 858e89e43..64fafbe18 100644 --- a/src/rpc/cli.cpp +++ b/src/rpc/cli.cpp @@ -118,6 +118,14 @@ void cli::run() else std::cout << itr->second( result, args ) << "\n"; } + catch ( const std::bad_alloc& ) + { + throw; + } + catch ( const boost::interprocess::bad_alloc& ) + { + throw; + } catch ( const fc::exception& e ) { std::cout << e.to_detail_string() << "\n"; diff --git a/src/rpc/http_api.cpp b/src/rpc/http_api.cpp index d20e4528c..41b009f26 100644 --- a/src/rpc/http_api.cpp +++ b/src/rpc/http_api.cpp @@ -115,6 +115,14 @@ void http_api_connection::on_request( const fc::http::request& req, const fc::ht resp_body = fc::json::to_string( fc::rpc::response( *call.id, result ) ); resp_status = http::reply::OK; } + catch ( const std::bad_alloc& ) + { + throw; + } + catch ( const boost::interprocess::bad_alloc& ) + { + throw; + } catch ( const fc::exception& e ) { handle_error_inner(e); @@ -130,6 +138,14 @@ void http_api_connection::on_request( const fc::http::request& req, const fc::ht resp_body = ""; } } + catch ( const std::bad_alloc& ) + { + throw; + } + catch ( const boost::interprocess::bad_alloc& ) + { + throw; + } catch ( const fc::exception& e ) { handle_error(e); @@ -145,6 +161,14 @@ void http_api_connection::on_request( const fc::http::request& req, const fc::ht resp.set_length( resp_body.length() ); resp.write( resp_body.c_str(), resp_body.length() ); } + catch ( const std::bad_alloc& ) + { + throw; + } + catch ( const boost::interprocess::bad_alloc& ) + { + throw; + } catch( const fc::exception& e ) { wdump((e.to_detail_string())); diff --git a/src/rpc/websocket_api.cpp b/src/rpc/websocket_api.cpp index ad1cee812..f89e2f0c0 100644 --- a/src/rpc/websocket_api.cpp +++ b/src/rpc/websocket_api.cpp @@ -123,6 +123,14 @@ std::string websocket_api_connection::on_message( return reply; } } + catch ( const std::bad_alloc& ) + { + throw; + } + catch ( const boost::interprocess::bad_alloc& ) + { + throw; + } catch ( const fc::exception& e ) { optexcept = handle_error_inner(e); @@ -147,6 +155,14 @@ std::string websocket_api_connection::on_message( _rpc_state.handle_reply( reply ); } } + catch ( const std::bad_alloc& ) + { + throw; + } + catch ( const boost::interprocess::bad_alloc& ) + { + throw; + } catch ( const fc::exception& e ) { return handle_error(e); From a62c48b21a2028eaa57249372fa65f150b5cdffe Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Thu, 20 Aug 2020 15:08:07 -0500 Subject: [PATCH 043/124] Add missing return --- include/fc/io/raw_variant.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/include/fc/io/raw_variant.hpp b/include/fc/io/raw_variant.hpp index e80f39011..925040062 100644 --- a/include/fc/io/raw_variant.hpp +++ b/include/fc/io/raw_variant.hpp @@ -119,6 +119,7 @@ namespace fc { namespace raw { blob val; raw::unpack(s,val); v = fc::move(val); + return; } default: FC_THROW_EXCEPTION( parse_error_exception, "Unknown Variant Type ${t}", ("t", t) ); From 04ff66758ff0660d616fd9a63163fbcac14158d4 Mon Sep 17 00:00:00 2001 From: Huang-Ming Huang Date: Mon, 24 Aug 2020 11:20:24 -0500 Subject: [PATCH 044/124] Fix unnecessary object copying --- src/network/http/http_client.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/network/http/http_client.cpp b/src/network/http/http_client.cpp index 4f7c379d6..64a929fe2 100644 --- a/src/network/http/http_client.cpp +++ b/src/network/http/http_client.cpp @@ -373,8 +373,7 @@ class http_client_impl { excp = std::make_shared(err_var["code"].as_int64(), err_var["name"].as_string(), err_var["what"].as_string()); if (err_var.contains("details")) { - auto details = err_var["details"].get_array(); - for (const auto dvar : details) { + for (const auto& dvar : err_var["details"].get_array()) { excp->append_log(FC_LOG_MESSAGE(error, dvar.get_object()["message"].as_string())); } } From 06d67a1402f42033d2f97e5055870c07d2b245e5 Mon Sep 17 00:00:00 2001 From: Huang-Ming Huang Date: Tue, 25 Aug 2020 16:19:35 -0500 Subject: [PATCH 045/124] remove unity build --- CMakeLists.txt | 6 ------ 1 file changed, 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 420f85352..2e09ce3c3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -123,12 +123,6 @@ list(APPEND sources ${fc_headers}) setup_library( fc SOURCES ${sources} LIBRARY_TYPE STATIC DONT_INSTALL_LIBRARY ) -if(ENABLE_UNITY_BUILD) - set_source_files_properties(src/io/json.cpp - PROPERTIES SKIP_UNITY_BUILD_INCLUSION TRUE) -endif() - - function(detect_thread_name) include(CheckSymbolExists) list(APPEND CMAKE_REQUIRED_DEFINITIONS -D_GNU_SOURCE) From 4b6855299f5d208bf8c408b7fdc8d251d44b2213 Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Wed, 21 Oct 2020 13:11:33 -0500 Subject: [PATCH 046/124] Fix support for stdout --- src/log/console_appender.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/log/console_appender.cpp b/src/log/console_appender.cpp index 025344b1e..45992f9db 100644 --- a/src/log/console_appender.cpp +++ b/src/log/console_appender.cpp @@ -20,7 +20,7 @@ namespace fc { public: config cfg; color::type lc[log_level::off+1]; - bool use_syslog_header{getenv("JOURNAL_STREAM") != nullptr}; + bool use_syslog_header{getenv("JOURNAL_STREAM") != nullptr}; #ifdef WIN32 HANDLE console_handle; #endif @@ -48,10 +48,10 @@ namespace fc { #endif my->cfg = console_appender_config; #ifdef WIN32 - if (my->cfg.stream = stream::std_error) - my->console_handle = GetStdHandle(STD_ERROR_HANDLE); - else if (my->cfg.stream = stream::std_out) - my->console_handle = GetStdHandle(STD_OUTPUT_HANDLE); + if (my->cfg.stream == stream::std_error) + my->console_handle = GetStdHandle(STD_ERROR_HANDLE); + else if (my->cfg.stream == stream::std_out) + my->console_handle = GetStdHandle(STD_OUTPUT_HANDLE); #endif for( int i = 0; i < log_level::off+1; ++i ) @@ -94,7 +94,7 @@ namespace fc { //fc::string message = fc::format_string( m.get_format(), m.get_data() ); //fc::variant lmsg(m); - FILE* out = stream::std_error ? stderr : stdout; + FILE* out = my->cfg.stream == stream::std_error ? stderr : stdout; //fc::string fmt_str = fc::format_string( cfg.format, mutable_variant_object(m.get_context())( "message", message) ); @@ -150,7 +150,7 @@ namespace fc { void console_appender::print( const std::string& text, color::type text_color ) { - FILE* out = stream::std_error ? stderr : stdout; + FILE* out = my->cfg.stream == stream::std_error ? stderr : stdout; #ifdef WIN32 if (my->console_handle != INVALID_HANDLE_VALUE) From 27a2c6076ee3ddd9b1b03ad6de2ede53c8ae8a44 Mon Sep 17 00:00:00 2001 From: Matt Witherspoon <32485495+spoonincode@users.noreply.github.com> Date: Fri, 23 Oct 2020 14:11:28 -0400 Subject: [PATCH 047/124] add options for not using GMP and for static linking GMP --- CMakeModules/FindGMP.cmake | 8 +++++- secp256k1/CMakeLists.txt | 25 ++++++++++++++++--- .../libsecp256k1-config.h | 0 .../config_without_gmp/libsecp256k1-config.h | 20 +++++++++++++++ 4 files changed, 48 insertions(+), 5 deletions(-) rename secp256k1/{ => config_with_gmp}/libsecp256k1-config.h (100%) create mode 100644 secp256k1/config_without_gmp/libsecp256k1-config.h diff --git a/CMakeModules/FindGMP.cmake b/CMakeModules/FindGMP.cmake index b6a402d0b..3aaa4b36d 100644 --- a/CMakeModules/FindGMP.cmake +++ b/CMakeModules/FindGMP.cmake @@ -1,3 +1,5 @@ +# This module's inputs: +# GMP_STATIC - static link GMP # This module defines: # GMP_FOUND - system has GMP lib # GMP_INCLUDE_DIR - the GMP include directory @@ -32,7 +34,11 @@ else() ) set(PREVIOUS_CMAKE_FIND_LIBRARY_SUFFIXES "${CMAKE_FIND_LIBRARY_SUFFIXES}") - set(CMAKE_FIND_LIBRARY_SUFFIXES "${CMAKE_SHARED_LIBRARY_SUFFIX}") + if(GMP_STATIC) + set(CMAKE_FIND_LIBRARY_SUFFIXES "${CMAKE_STATIC_LIBRARY_SUFFIX}") + else() + set(CMAKE_FIND_LIBRARY_SUFFIXES "${CMAKE_SHARED_LIBRARY_SUFFIX}") + endif() find_library(GMP_LIBRARIES NAMES gmp HINTS ENV GMP_LIB_DIR diff --git a/secp256k1/CMakeLists.txt b/secp256k1/CMakeLists.txt index 3be0ea4a6..5d2ab0f9e 100644 --- a/secp256k1/CMakeLists.txt +++ b/secp256k1/CMakeLists.txt @@ -1,7 +1,24 @@ -cmake_minimum_required(VERSION 3.4) -project(secp256k1) +set(GMP_USAGES "On;Auto;Off") +set(GMP_USAGE "On" CACHE STRING "libgmp usage: On: required; Auto: used if present; Off: not used") +set_property(CACHE GMP_USAGE PROPERTY STRINGS ${GMP_USAGES}) -find_package(GMP REQUIRED) +if(NOT GMP_USAGE IN_LIST GMP_USAGES) + message(FATAL_ERROR "GMP_USAGE must be set to one of: ${GMP_USAGES}") +endif() + +if(GMP_USAGE STREQUAL "On") + find_package(GMP REQUIRED) +elseif(GMP_USAGE) + find_package(GMP) +endif() + +if(GMP_FOUND) + set(SECP256K1_CONFIG_INC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/config_with_gmp") +else() + set(SECP256K1_CONFIG_INC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/config_without_gmp") + unset(GMP_INCLUDE_DIR CACHE) + unset(GMP_LIBRARIES CACHE) +endif() add_library(secp256k1 STATIC upstream/src/secp256k1.c @@ -13,7 +30,7 @@ target_include_directories(secp256k1 ${CMAKE_CURRENT_SOURCE_DIR}/upstream/include PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/upstream/src - ${CMAKE_CURRENT_SOURCE_DIR} + ${SECP256K1_CONFIG_INC_DIR} ${GMP_INCLUDE_DIR} ) diff --git a/secp256k1/libsecp256k1-config.h b/secp256k1/config_with_gmp/libsecp256k1-config.h similarity index 100% rename from secp256k1/libsecp256k1-config.h rename to secp256k1/config_with_gmp/libsecp256k1-config.h diff --git a/secp256k1/config_without_gmp/libsecp256k1-config.h b/secp256k1/config_without_gmp/libsecp256k1-config.h new file mode 100644 index 000000000..24ed1c987 --- /dev/null +++ b/secp256k1/config_without_gmp/libsecp256k1-config.h @@ -0,0 +1,20 @@ +#pragma once + +//optimizations that any compiler we target have +#define HAVE_BUILTIN_CLZLL 1 +#define HAVE_BUILTIN_EXPECT 1 +#define HAVE___INT128 1 + +//use internal field & num impls +#define USE_FIELD_INV_BUILTIN 1 +#define USE_SCALAR_INV_BUILTIN 1 +#define USE_NUM_NONE 1 + +//use impls best for 64-bit +#define USE_FIELD_5X52 1 +#define USE_SCALAR_4X64 1 + +//enable asm +#ifdef __x86_64__ + #define USE_ASM_X86_64 1 +#endif From 88ecbef6f8857b94bec116b78042f95433be37c1 Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Mon, 26 Oct 2020 12:24:17 -0500 Subject: [PATCH 048/124] Allow empty responses --- include/fc/log/trace.hpp | 163 ++++++++++++++++++++++++++++ include/fc/log/zipkin_appender.hpp | 49 +++++++++ src/log/zipkin_appender.cpp | 164 +++++++++++++++++++++++++++++ src/network/http/http_client.cpp | 7 +- 4 files changed, 382 insertions(+), 1 deletion(-) create mode 100644 include/fc/log/trace.hpp create mode 100644 include/fc/log/zipkin_appender.hpp create mode 100644 src/log/zipkin_appender.cpp diff --git a/include/fc/log/trace.hpp b/include/fc/log/trace.hpp new file mode 100644 index 000000000..8d87a6aeb --- /dev/null +++ b/include/fc/log/trace.hpp @@ -0,0 +1,163 @@ +#pragma once + +#include +#include +#include +#include + +/// Simple wrappers for zipkin tracing, see zipkin_appender +namespace fc { + inline std::string zipkin_logger_name = "zipkin"; + + struct zipkin_span { + explicit zipkin_span( std::string name, const fc::log_context& lc, uint64_t parent_id = 0 ) + : id( log_config::get_next_unique_id() ) + , parent_id( parent_id ) + , start( time_point::now() ) + , name( std::move(name) ) + , log_context( lc ) + {} + + explicit zipkin_span( uint64_t id, std::string name, const fc::log_context& lc, uint64_t parent_id = 0 ) + : id( id ) + , parent_id( parent_id ) + , start( time_point::now() ) + , name( std::move(name) ) + , log_context( lc ) + {} + + zipkin_span( const zipkin_span& ) = delete; + zipkin_span& operator=( const zipkin_span& ) = delete; + zipkin_span& operator=( zipkin_span&& ) = delete; + + zipkin_span( zipkin_span&& rhs ) noexcept + : id( rhs.id ) + , parent_id( rhs.parent_id ) + , start( rhs.start ) + , name( std::move( rhs.name ) ) + , log_context( std::move( rhs.log_context ) ) + , data( std::move( rhs.data ) ) + { + rhs.id = 0; + } + + ~zipkin_span() { + if( id == 0 ) + return; + try { + auto log = fc::logger::get( zipkin_logger_name ); + if( log.is_enabled( fc::log_level::debug ) ) { + data["zipkin.id"] = id; + static_assert( std::is_same::value, "Expect to store int64_t"); + data["zipkin.timestamp"] = start.time_since_epoch().count(); + static_assert( std::is_same::value, "Expect to store int64_t"); + data["zipkin.duration"] = (time_point::now() - start).count(); + data["zipkin.name"] = std::move(name); + if( parent_id != 0 ) { + data["zipkin.traceId"] = parent_id; + data["zipkin.parentId"] = parent_id; + } else { + data["zipkin.traceId"] = id; + } + log.log( fc::log_message( log_context, "", std::move( data ) ) ); + } + } catch( ... ) {} + } + + template + void add_tag( const std::string& key, T&& var ) { + data( key, std::forward( var ) ); + } + + struct token { + friend zipkin_span; + friend struct zipkin_trace; + friend struct optional_trace; + constexpr explicit operator bool() const noexcept { return id != 0; } + private: + explicit token(uint64_t id) + : id(id) {} + uint64_t id; + }; + + token get_token() const { return token{id}; }; + + static uint64_t to_id( const fc::sha256& id ) { + return id._hash[3]; + } + + template + static uint64_t to_id( const T& id ) { + static_assert( std::is_same_v, "expected uint64_t" ); + return id.data()[3]; + } + + private: + uint64_t id; + // zipkin traceId and parentId are same since only allowing trace with span children, no children of spans + const uint64_t parent_id; + const fc::time_point start; + std::string name; + fc::log_context log_context; + fc::mutable_variant_object data; + }; + + struct zipkin_trace : public zipkin_span { + using zipkin_span::zipkin_span; + [[nodiscard]] std::optional create_span(std::string name, const fc::log_context& lc) const { + return zipkin_span{ std::move(name), lc, get_token().id }; + } + [[nodiscard]] static std::optional create_span_from_token( zipkin_span::token token, std::string name, const fc::log_context& lc) { + return zipkin_span{ std::move(name), lc, token.id }; + } + }; + + struct optional_trace { + std::optional opt; + constexpr explicit operator bool() const noexcept { return opt.has_value(); } + [[nodiscard]] zipkin_span::token get_token() const { + return opt ? opt->get_token() : zipkin_span::token(0); + } + }; + +} // fc + +/// @param TRACE_STR const char* identifier for trace +/// @return implementation defined type RAII object that submits trace on exit of scope +#define fc_create_trace( TRACE_STR ) \ + ::fc::logger::get(::fc::zipkin_logger_name).is_enabled( ::fc::log_level::debug ) ? \ + ::fc::optional_trace{ ::std::optional<::fc::zipkin_trace>( ::std::in_place, (TRACE_STR), FC_LOG_CONTEXT( debug ) ) } \ + : ::fc::optional_trace{}; + +/// @param TRACE_STR const char* identifier for trace +/// @param TRACE_ID fc::sha256 id to use +/// @return implementation defined type RAII object that submits trace on exit of scope +#define fc_create_trace_with_id( TRACE_STR, TRACE_ID ) \ + ::fc::logger::get(::fc::zipkin_logger_name).is_enabled( ::fc::log_level::debug ) ? \ + ::fc::optional_trace{ ::std::optional<::fc::zipkin_trace>( ::std::in_place, ::fc::zipkin_span::to_id(TRACE_ID), (TRACE_STR), FC_LOG_CONTEXT( debug ) ) } \ + : ::fc::optional_trace{}; + +/// @param TRACE_VARNAME variable returned from fc_create_trace +/// @param SPAN_STR const char* indentifier +/// @return implementation defined type RAII object that submits span on exit of scope +#define fc_create_span( TRACE_VARNAME, SPAN_STR ) \ + ( (TRACE_VARNAME) && ::fc::logger::get(::fc::zipkin_logger_name).is_enabled( ::fc::log_level::debug ) ) ? \ + (TRACE_VARNAME).opt->create_span( (SPAN_STR), FC_LOG_CONTEXT( debug ) ) \ + : ::std::optional<::fc::zipkin_span>{}; + +/// @param TRACE_TOKEN variable returned from trace.get_token() +/// @param SPAN_STR const char* indentifier +/// @return implementation defined type RAII object that submits span on exit of scope +#define fc_create_span_from_token( TRACE_TOKEN, SPAN_STR ) \ + ( (TRACE_TOKEN) && ::fc::logger::get(::fc::zipkin_logger_name).is_enabled( ::fc::log_level::debug ) ) ? \ + ::fc::zipkin_trace::create_span_from_token( (TRACE_TOKEN), (SPAN_STR), FC_LOG_CONTEXT( debug ) ) \ + : ::std::optional<::fc::zipkin_span>{}; + +/// @param SPAN_VARNAME variable returned from fc_create_span +/// @param TAG_KEY_STR const char* key +/// @param TAG_VALUE any fc::variant type +#define fc_add_tag( SPAN_VARNAME, TAG_KEY_STR, TAG_VALUE) \ + FC_MULTILINE_MACRO_BEGIN \ + if( (SPAN_VARNAME) && ::fc::logger::get(::fc::zipkin_logger_name).is_enabled( ::fc::log_level::debug ) ) \ + (SPAN_VARNAME)->add_tag( (TAG_KEY_STR), (TAG_VALUE) ); \ + FC_MULTILINE_MACRO_END diff --git a/include/fc/log/zipkin_appender.hpp b/include/fc/log/zipkin_appender.hpp new file mode 100644 index 000000000..293c99b9b --- /dev/null +++ b/include/fc/log/zipkin_appender.hpp @@ -0,0 +1,49 @@ +#pragma once + +#include +#include +#include + +namespace fc +{ + // Active Log appender that sends zipkin messages in JSON format + // https://zipkin.io/zipkin-api/ + // + // log_message should contain following variant data + // uint64_t zipkin.traceId - unique id for trace, all children spans shared same id + // std::string zipkin.name - logical operation, should have low cardinality + // uint64_t zipkin.parentId - The parent span id, or absent if root span + // uint64_t zipkin.id - unique if for this span + // int64_t zipkin.timestamp - epoch microseconds of start of span + // int64_t zipkin.duration - microseconds of span + + class zipkin_appender final : public appender { + public: + struct config { + std::string endpoint = "http://127.0.0.1:9411"; + std::string path = "/api/v2/spans"; // path to post span + std::string service_name = "unknown"; // localEndpoint.serviceName reported on each Span + uint32_t timeout_us = 200*1000; // 200ms + }; + + explicit zipkin_appender( const variant& args ); + ~zipkin_appender() = default; + + // no-op. connection made on first log() + void initialize( boost::asio::io_service& io_service ) override; + + // finish logging all queued up spans + void shutdown() override; + + // Logs zipkin json via http on separate thread + void log( const log_message& m ) override; + + private: + class impl; + std::shared_ptr my; + }; +} // namespace fc + +#include +FC_REFLECT( fc::zipkin_appender::config, + (endpoint)(path)(service_name)(timeout_us) ) diff --git a/src/log/zipkin_appender.cpp b/src/log/zipkin_appender.cpp new file mode 100644 index 000000000..209fbe722 --- /dev/null +++ b/src/log/zipkin_appender.cpp @@ -0,0 +1,164 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +namespace fc { + +class zipkin_appender::impl { +public: + static constexpr uint32_t max_consecutive_errors = 9; + + config cfg; + http_client http; + std::atomic consecutive_errors = 0; + std::optional endpoint; + std::thread thread; + boost::asio::io_context ctx; + boost::asio::strand work_strand = boost::asio::make_strand(ctx); + boost::asio::executor_work_guard work_guard = boost::asio::make_work_guard(ctx); + + explicit impl( config c ) : + cfg( std::move( c ) ) { + } + + void init(); + + void log( const log_message& message ); + + ~impl(); +}; + +void zipkin_appender::impl::init() { + thread = std::thread( [this]() { + fc::set_os_thread_name( "zipkin" ); + while( true ) { + try { + ctx.run(); + break; + } FC_LOG_AND_DROP(); + } + } ); +} + +zipkin_appender::impl::~impl() { + try { + work_guard.reset(); // drain the queue + thread.join(); + } catch (...) {} +} + +zipkin_appender::zipkin_appender( const variant& args ) : + my( new impl( args.as() ) ) { +} + +void zipkin_appender::initialize( boost::asio::io_service& io_service ) { + my->init(); +} + +void zipkin_appender::shutdown() { + my.reset(); +} + +fc::variant create_zipkin_variant( const log_message& message, const std::string& service_name ) { + // https://zipkin.io/zipkin-api/ + // std::string traceId; // [a-f0-9]{16,32} unique id for trace, all children spans shared same id + // std::string name; // logical operation, should have low cardinality + // std::string parentId; // The parent span id, or absent if root span + // std::string id // a-f0-9]{16} + // int64_t timestamp // epoch microseconds of start of span + // int64_t duration // microseconds of span + + log_context context = message.get_context(); + fc::mutable_variant_object d = message.get_data(); + + fc::mutable_variant_object mvo; + auto i = d.find( "zipkin.traceId" ); + if( i != d.end() && i->value().is_uint64() ) { + uint64_t v = i->value().as_uint64(); + mvo( "traceId", fc::to_hex( reinterpret_cast(&v), sizeof( v ) ) ); + d.erase( "zipkin.traceId" ); + } + i = d.find( "zipkin.id" ); + if( i != d.end() && i->value().is_uint64() ) { + uint64_t v = i->value().as_uint64(); + mvo( "id", fc::to_hex( reinterpret_cast(&v), sizeof( v ) ) ); + d.erase( "zipkin.id" ); + } + i = d.find( "zipkin.parentId" ); + if( i != d.end() && i->value().is_uint64() ) { + uint64_t v = i->value().as_uint64(); + if( v != 0 ) + mvo( "parentId", fc::to_hex( reinterpret_cast(&v), sizeof( v ) ) ); + d.erase( "zipkin.parentId" ); + } + i = d.find( "zipkin.name" ); + if( i != d.end() ) { + mvo( "name", i->value() ); + d.erase( "zipkin.name" ); + } + i = d.find( "zipkin.timestamp" ); + if( i != d.end() ) { + mvo( "timestamp", i->value() ); + d.erase( "zipkin.timestamp" ); + } + i = d.find( "zipkin.duration" ); + if( i != d.end() ) { + mvo( "duration", i->value() ); + d.erase( "zipkin.duration" ); + } + + mvo( "localEndpoint", fc::variant_object( "serviceName", service_name ) ); + + mvo( "tags", d ); + + // /api/v2/spans takes an array of spans + fc::variants result; + result.emplace_back( mvo ); + + return result; +} + +void zipkin_appender::log( const log_message& message ) { + if( !my || my->consecutive_errors > my->max_consecutive_errors ) + return; + + boost::asio::post(my->work_strand, [this, message]() { + my->log( message ); + }); +} + +void zipkin_appender::impl::log( const log_message& message ) { + if( consecutive_errors > max_consecutive_errors ) + return; + + try { + auto deadline = fc::time_point::now() + fc::microseconds( cfg.timeout_us ); + if( !endpoint ) { + endpoint = url( cfg.endpoint + cfg.path ); + std::cout << "Connecting to zipkin: " << (std::string) *endpoint << std::endl; + } + + http.post_sync( *endpoint, create_zipkin_variant( message, cfg.service_name ), deadline ); + + consecutive_errors = 0; + } catch( const fc::exception& e ) { + std::cerr << "Unable to connect to zipkin: " << cfg.endpoint + cfg.path << ", error: " << e.to_detail_string() << std::endl; + } catch( const std::exception& e ) { + std::cerr << "Unable to connect to zipkin: " << cfg.endpoint + cfg.path << ", error: " << e.what() << std::endl; + } catch( ... ) { + std::cerr << "Unknown error connecting to zipkin: " << cfg.endpoint + cfg.path << std::endl; + } + ++consecutive_errors; +} + +} // fc diff --git a/src/network/http/http_client.cpp b/src/network/http/http_client.cpp index 64a929fe2..8233b8e07 100644 --- a/src/network/http/http_client.cpp +++ b/src/network/http/http_client.cpp @@ -365,7 +365,12 @@ class http_client_impl { eraser.cancel(); } - auto result = json::from_string(res.body()); + fc::variant result; + if( !res.body().empty() ) { + try { + result = json::from_string( res.body() ); + } catch( ... ) {} + } if (res.result() == http::status::internal_server_error) { fc::exception_ptr excp; try { From a256e934679b91db24853ec86e0615aa77b770fd Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Mon, 26 Oct 2020 12:24:46 -0500 Subject: [PATCH 049/124] Add zipkin_appender --- CMakeLists.txt | 1 + include/fc/log/appender.hpp | 1 + include/fc/log/logger_config.hpp | 5 +++++ src/log/appender.cpp | 3 ++- src/log/logger_config.cpp | 23 ++++++++++++++++++++++- 5 files changed, 31 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2e09ce3c3..8117739cf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -111,6 +111,7 @@ set( fc_sources src/compress/smaz.cpp src/compress/zlib.cpp src/log/gelf_appender.cpp + src/log/zipkin_appender.cpp ) file( GLOB_RECURSE fc_headers ${CMAKE_CURRENT_SOURCE_DIR} *.hpp *.h ) diff --git a/include/fc/log/appender.hpp b/include/fc/log/appender.hpp index c01aadb0e..87db64c33 100644 --- a/include/fc/log/appender.hpp +++ b/include/fc/log/appender.hpp @@ -37,6 +37,7 @@ namespace fc { typedef std::shared_ptr ptr; virtual void initialize( boost::asio::io_service& io_service ) = 0; + virtual void shutdown() {} virtual void log( const log_message& m ) = 0; }; } diff --git a/include/fc/log/logger_config.hpp b/include/fc/log/logger_config.hpp index 04de647d5..1e4a957aa 100644 --- a/include/fc/log/logger_config.hpp +++ b/include/fc/log/logger_config.hpp @@ -56,8 +56,12 @@ namespace fc { static void initialize_appenders( boost::asio::io_service& ios ); + static void shutdown_appenders(); + static bool configure_logging( const logging_config& l ); + static uint64_t get_next_unique_id(); + private: static log_config& get(); @@ -67,6 +71,7 @@ namespace fc { std::unordered_map appender_factory_map; std::unordered_map appender_map; std::unordered_map logger_map; + uint64_t next_id = 0; }; void configure_logging( const fc::path& log_config ); diff --git a/src/log/appender.cpp b/src/log/appender.cpp index b04244272..9c1038cd9 100644 --- a/src/log/appender.cpp +++ b/src/log/appender.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include @@ -10,6 +11,6 @@ namespace fc { static bool reg_console_appender = log_config::register_appender( "console" ); static bool reg_gelf_appender = log_config::register_appender( "gelf" ); static bool reg_dmlog_appender = log_config::register_appender( "dmlog" ); - + static bool reg_zipkin_appender = log_config::register_appender( "zipkin" ); } // namespace fc diff --git a/src/log/logger_config.cpp b/src/log/logger_config.cpp index 586909671..5fbc32327 100644 --- a/src/log/logger_config.cpp +++ b/src/log/logger_config.cpp @@ -7,8 +7,10 @@ #include #include #include +#include #include #include +#include namespace fc { @@ -25,6 +27,18 @@ namespace fc { return true; } + uint64_t log_config::get_next_unique_id() { + auto& lc = log_config::get(); + std::lock_guard g( lc.log_mutex ); + if( lc.next_id == 0 ) { + std::mt19937_64 engine( std::random_device{}() ); + std::uniform_int_distribution distribution; + lc.next_id = distribution( engine ); + } + return lc.next_id++; + } + + logger log_config::get_logger( const fc::string& name ) { std::lock_guard g( log_config::get().log_mutex ); return log_config::get().logger_map[name]; @@ -49,6 +63,12 @@ namespace fc { iter.second->initialize( ios ); } + void log_config::shutdown_appenders() { + std::lock_guard g( log_config::get().log_mutex ); + for( auto& iter : log_config::get().appender_map ) + iter.second->shutdown(); + } + void configure_logging( const fc::path& lc ) { configure_logging( fc::json::from_file(lc) ); } @@ -61,6 +81,7 @@ namespace fc { static bool reg_console_appender = log_config::register_appender( "console" ); static bool reg_gelf_appender = log_config::register_appender( "gelf" ); static bool reg_dmlog_appender = log_config::register_appender( "dmlog" ); + static bool reg_zipkin_appender = log_config::register_appender( "zipkin" ); std::lock_guard g( log_config::get().log_mutex ); log_config::get().logger_map.clear(); @@ -95,7 +116,7 @@ namespace fc { } } } - return reg_console_appender || reg_gelf_appender || reg_dmlog_appender; + return reg_console_appender || reg_gelf_appender || reg_dmlog_appender || reg_zipkin_appender; } catch ( exception& e ) { std::cerr< Date: Tue, 27 Oct 2020 08:43:47 -0500 Subject: [PATCH 050/124] Use default logger for logging in zipkin_appender. Do not allow zipkin_appender for default logger. --- src/log/logger_config.cpp | 11 +++++++++-- src/log/zipkin_appender.cpp | 8 ++++---- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/log/logger_config.cpp b/src/log/logger_config.cpp index 5fbc32327..07508d5b4 100644 --- a/src/log/logger_config.cpp +++ b/src/log/logger_config.cpp @@ -87,7 +87,7 @@ namespace fc { log_config::get().logger_map.clear(); log_config::get().appender_map.clear(); - //slog( "\n%s", fc::json::to_pretty_string(cfg).c_str() ); + appender::ptr zipkin_appender; for( size_t i = 0; i < cfg.appenders.size(); ++i ) { // create appender auto fact_itr = log_config::get().appender_factory_map.find( cfg.appenders[i].type ); @@ -97,6 +97,9 @@ namespace fc { } auto ap = fact_itr->second->create( cfg.appenders[i].args ); log_config::get().appender_map[cfg.appenders[i].name] = ap; + if( cfg.appenders[i].type == "zipkin" ) { + zipkin_appender = ap; + } } for( size_t i = 0; i < cfg.loggers.size(); ++i ) { auto lgr = log_config::get().logger_map[cfg.loggers[i].name]; @@ -112,7 +115,11 @@ namespace fc { for( auto a = cfg.loggers[i].appenders.begin(); a != cfg.loggers[i].appenders.end(); ++a ){ auto ap_it = log_config::get().appender_map.find(*a); if( ap_it != log_config::get().appender_map.end() ) { - lgr.add_appender(ap_it->second); + if( lgr.name() == DEFAULT_LOGGER && ap_it->second == zipkin_appender ) { + std::cerr << "warn: zipkin_appender not allowed for default logger" << std::endl; + } else { + lgr.add_appender( ap_it->second ); + } } } } diff --git a/src/log/zipkin_appender.cpp b/src/log/zipkin_appender.cpp index 209fbe722..d58c29379 100644 --- a/src/log/zipkin_appender.cpp +++ b/src/log/zipkin_appender.cpp @@ -145,18 +145,18 @@ void zipkin_appender::impl::log( const log_message& message ) { auto deadline = fc::time_point::now() + fc::microseconds( cfg.timeout_us ); if( !endpoint ) { endpoint = url( cfg.endpoint + cfg.path ); - std::cout << "Connecting to zipkin: " << (std::string) *endpoint << std::endl; + dlog( "Connecting to zipkin: ${e}", ("e", *endpoint) ); } http.post_sync( *endpoint, create_zipkin_variant( message, cfg.service_name ), deadline ); consecutive_errors = 0; } catch( const fc::exception& e ) { - std::cerr << "Unable to connect to zipkin: " << cfg.endpoint + cfg.path << ", error: " << e.to_detail_string() << std::endl; + wlog( "Unable to connect to zipkin: ${p}, error: ${e}", ("p", cfg.endpoint + cfg.path)("e", e.to_detail_string()) ); } catch( const std::exception& e ) { - std::cerr << "Unable to connect to zipkin: " << cfg.endpoint + cfg.path << ", error: " << e.what() << std::endl; + wlog( "Unable to connect to zipkin: ${p}, error: ${e}", ("p", cfg.endpoint + cfg.path)("e", e.what()) ); } catch( ... ) { - std::cerr << "Unknown error connecting to zipkin: " << cfg.endpoint + cfg.path << std::endl; + wlog( "Unable to connect to zipkin: ${p}, error: ${e}", ("p", cfg.endpoint + cfg.path)("e", "unknown error") ); } ++consecutive_errors; } From bddd252540f46391c8d8a863b65f82ccc63a70a2 Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Tue, 27 Oct 2020 13:17:33 -0500 Subject: [PATCH 051/124] Avoid random 0 --- src/log/logger_config.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/log/logger_config.cpp b/src/log/logger_config.cpp index 07508d5b4..f9c33641b 100644 --- a/src/log/logger_config.cpp +++ b/src/log/logger_config.cpp @@ -32,7 +32,7 @@ namespace fc { std::lock_guard g( lc.log_mutex ); if( lc.next_id == 0 ) { std::mt19937_64 engine( std::random_device{}() ); - std::uniform_int_distribution distribution; + std::uniform_int_distribution distribution(1); lc.next_id = distribution( engine ); } return lc.next_id++; From e089ce144886c6dea43bd0f0dfa62a0a4711b878 Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Tue, 27 Oct 2020 13:18:06 -0500 Subject: [PATCH 052/124] zipkin tags should be strings --- include/fc/log/trace.hpp | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/include/fc/log/trace.hpp b/include/fc/log/trace.hpp index 8d87a6aeb..482788442 100644 --- a/include/fc/log/trace.hpp +++ b/include/fc/log/trace.hpp @@ -4,6 +4,7 @@ #include #include #include +#include /// Simple wrappers for zipkin tracing, see zipkin_appender namespace fc { @@ -64,9 +65,27 @@ namespace fc { } catch( ... ) {} } + void add_tag( const std::string& key, const std::string& var ) { + // zipkin tags are required to be strings + data( key, var ); + } + void add_tag( const std::string& key, const char* var ) { + // zipkin tags are required to be strings + data( key, var ); + } + void add_tag( const std::string& key, bool v ) { + // zipkin tags are required to be strings + data( key, v ? "true" : "false" ); + } + template + typename std::enable_if_t>, void> + add_tag( const std::string& key, T&& var ) { + data( key, std::to_string( std::forward( var ) ) ); + } template - void add_tag( const std::string& key, T&& var ) { - data( key, std::forward( var ) ); + typename std::enable_if_t>, void> + add_tag( const std::string& key, T&& var ) { + data( key, (std::string) var ); } struct token { @@ -94,7 +113,8 @@ namespace fc { private: uint64_t id; - // zipkin traceId and parentId are same since only allowing trace with span children, no children of spans + // zipkin traceId and parentId are same (when parent_id set) since only allowing trace with span children. + // Not currently supporting spans with children, only trace with children spans. const uint64_t parent_id; const fc::time_point start; std::string name; @@ -154,10 +174,10 @@ namespace fc { : ::std::optional<::fc::zipkin_span>{}; /// @param SPAN_VARNAME variable returned from fc_create_span -/// @param TAG_KEY_STR const char* key -/// @param TAG_VALUE any fc::variant type -#define fc_add_tag( SPAN_VARNAME, TAG_KEY_STR, TAG_VALUE) \ +/// @param TAG_KEY_STR string key +/// @param TAG_VALUE string value +#define fc_add_tag( SPAN_VARNAME, TAG_KEY_STR, TAG_VALUE_STR) \ FC_MULTILINE_MACRO_BEGIN \ if( (SPAN_VARNAME) && ::fc::logger::get(::fc::zipkin_logger_name).is_enabled( ::fc::log_level::debug ) ) \ - (SPAN_VARNAME)->add_tag( (TAG_KEY_STR), (TAG_VALUE) ); \ + (SPAN_VARNAME)->add_tag( (TAG_KEY_STR), (TAG_VALUE_STR) ); \ FC_MULTILINE_MACRO_END From 3b3eda950116c5e2d4294a67faadffd6bd560dbb Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Tue, 27 Oct 2020 13:18:25 -0500 Subject: [PATCH 053/124] Enforce id and traceId required --- src/log/zipkin_appender.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/log/zipkin_appender.cpp b/src/log/zipkin_appender.cpp index d58c29379..a272ee5ff 100644 --- a/src/log/zipkin_appender.cpp +++ b/src/log/zipkin_appender.cpp @@ -4,12 +4,12 @@ #include #include #include -#include #include +#include +#include #include -#include #include namespace fc { @@ -87,12 +87,16 @@ fc::variant create_zipkin_variant( const log_message& message, const std::string uint64_t v = i->value().as_uint64(); mvo( "traceId", fc::to_hex( reinterpret_cast(&v), sizeof( v ) ) ); d.erase( "zipkin.traceId" ); + } else { + FC_THROW_EXCEPTION( parse_error_exception, "zipkin.traceId required" ); } i = d.find( "zipkin.id" ); if( i != d.end() && i->value().is_uint64() ) { uint64_t v = i->value().as_uint64(); mvo( "id", fc::to_hex( reinterpret_cast(&v), sizeof( v ) ) ); d.erase( "zipkin.id" ); + } else { + FC_THROW_EXCEPTION( parse_error_exception, "zipkin.id required" ); } i = d.find( "zipkin.parentId" ); if( i != d.end() && i->value().is_uint64() ) { From e7ad1fb0abd4f2e322397fe6db9eb2c61912c3f7 Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Fri, 30 Oct 2020 09:31:35 -0500 Subject: [PATCH 054/124] Fix shutdown deadlock issue. Disallow 0 id. Moved shutdown to logger --- include/fc/log/logger.hpp | 2 ++ include/fc/log/logger_config.hpp | 2 -- include/fc/log/trace.hpp | 9 +++++---- src/log/logger.cpp | 16 ++++++++++++++++ src/log/logger_config.cpp | 12 +----------- src/log/zipkin_appender.cpp | 18 +++++++++++++----- 6 files changed, 37 insertions(+), 22 deletions(-) diff --git a/include/fc/log/logger.hpp b/include/fc/log/logger.hpp index 803a2de0a..509282590 100644 --- a/include/fc/log/logger.hpp +++ b/include/fc/log/logger.hpp @@ -50,6 +50,8 @@ namespace fc bool is_enabled( log_level e )const; void log( log_message m ); + void shutdown(); + private: friend struct log_config; void add_appender( const std::shared_ptr& a ); diff --git a/include/fc/log/logger_config.hpp b/include/fc/log/logger_config.hpp index 1e4a957aa..b4e6ae42c 100644 --- a/include/fc/log/logger_config.hpp +++ b/include/fc/log/logger_config.hpp @@ -56,8 +56,6 @@ namespace fc { static void initialize_appenders( boost::asio::io_service& ios ); - static void shutdown_appenders(); - static bool configure_logging( const logging_config& l ); static uint64_t get_next_unique_id(); diff --git a/include/fc/log/trace.hpp b/include/fc/log/trace.hpp index 482788442..c8c3041bf 100644 --- a/include/fc/log/trace.hpp +++ b/include/fc/log/trace.hpp @@ -8,7 +8,7 @@ /// Simple wrappers for zipkin tracing, see zipkin_appender namespace fc { - inline std::string zipkin_logger_name = "zipkin"; + inline const std::string zipkin_logger_name = "zipkin"; struct zipkin_span { explicit zipkin_span( std::string name, const fc::log_context& lc, uint64_t parent_id = 0 ) @@ -78,12 +78,12 @@ namespace fc { data( key, v ? "true" : "false" ); } template - typename std::enable_if_t>, void> + std::enable_if_t>, void> add_tag( const std::string& key, T&& var ) { data( key, std::to_string( std::forward( var ) ) ); } template - typename std::enable_if_t>, void> + std::enable_if_t>, void> add_tag( const std::string& key, T&& var ) { data( key, (std::string) var ); } @@ -102,7 +102,8 @@ namespace fc { token get_token() const { return token{id}; }; static uint64_t to_id( const fc::sha256& id ) { - return id._hash[3]; + // avoid 0 since id of 0 is used as a flag + return id._hash[3] == 0 ? 1 : id._hash[3]; } template diff --git a/src/log/logger.cpp b/src/log/logger.cpp index edc029c34..bf88729d6 100644 --- a/src/log/logger.cpp +++ b/src/log/logger.cpp @@ -82,6 +82,22 @@ namespace fc { } } + void logger::shutdown() { + std::unique_lock g( log_config::get().log_mutex ); + + for( auto& a : my->_appenders ) { + try { + a->shutdown(); + } catch( fc::exception& er ) { + std::cerr << "ERROR: logger::shutdown fc::exception: " << er.to_detail_string() << std::endl; + } catch( const std::exception& e ) { + std::cerr << "ERROR: logger::shutdown std::exception: " << e.what() << std::endl; + } catch( ... ) { + std::cerr << "ERROR: logger::shutdown unknown exception: " << std::endl; + } + } + } + void logger::set_name( const fc::string& n ) { my->_name = n; } const fc::string& logger::name()const { return my->_name; } diff --git a/src/log/logger_config.cpp b/src/log/logger_config.cpp index f9c33641b..3372e153f 100644 --- a/src/log/logger_config.cpp +++ b/src/log/logger_config.cpp @@ -63,12 +63,6 @@ namespace fc { iter.second->initialize( ios ); } - void log_config::shutdown_appenders() { - std::lock_guard g( log_config::get().log_mutex ); - for( auto& iter : log_config::get().appender_map ) - iter.second->shutdown(); - } - void configure_logging( const fc::path& lc ) { configure_logging( fc::json::from_file(lc) ); } @@ -87,7 +81,6 @@ namespace fc { log_config::get().logger_map.clear(); log_config::get().appender_map.clear(); - appender::ptr zipkin_appender; for( size_t i = 0; i < cfg.appenders.size(); ++i ) { // create appender auto fact_itr = log_config::get().appender_factory_map.find( cfg.appenders[i].type ); @@ -97,9 +90,6 @@ namespace fc { } auto ap = fact_itr->second->create( cfg.appenders[i].args ); log_config::get().appender_map[cfg.appenders[i].name] = ap; - if( cfg.appenders[i].type == "zipkin" ) { - zipkin_appender = ap; - } } for( size_t i = 0; i < cfg.loggers.size(); ++i ) { auto lgr = log_config::get().logger_map[cfg.loggers[i].name]; @@ -115,7 +105,7 @@ namespace fc { for( auto a = cfg.loggers[i].appenders.begin(); a != cfg.loggers[i].appenders.end(); ++a ){ auto ap_it = log_config::get().appender_map.find(*a); if( ap_it != log_config::get().appender_map.end() ) { - if( lgr.name() == DEFAULT_LOGGER && ap_it->second == zipkin_appender ) { + if( lgr.name() == DEFAULT_LOGGER && (dynamic_cast(ap_it->second.get()) != nullptr) ) { std::cerr << "warn: zipkin_appender not allowed for default logger" << std::endl; } else { lgr.add_appender( ap_it->second ); diff --git a/src/log/zipkin_appender.cpp b/src/log/zipkin_appender.cpp index a272ee5ff..36b6ec4ab 100644 --- a/src/log/zipkin_appender.cpp +++ b/src/log/zipkin_appender.cpp @@ -62,10 +62,13 @@ zipkin_appender::zipkin_appender( const variant& args ) : } void zipkin_appender::initialize( boost::asio::io_service& io_service ) { - my->init(); + // called holding the log_config log_mutex + if( my ) + my->init(); } void zipkin_appender::shutdown() { + // called holding the log_config log_mutex my.reset(); } @@ -133,6 +136,7 @@ fc::variant create_zipkin_variant( const log_message& message, const std::string } void zipkin_appender::log( const log_message& message ) { + // called holding the log_config log_mutex if( !my || my->consecutive_errors > my->max_consecutive_errors ) return; @@ -149,18 +153,22 @@ void zipkin_appender::impl::log( const log_message& message ) { auto deadline = fc::time_point::now() + fc::microseconds( cfg.timeout_us ); if( !endpoint ) { endpoint = url( cfg.endpoint + cfg.path ); - dlog( "Connecting to zipkin: ${e}", ("e", *endpoint) ); + std::cout << "info: connecting to zipkin: " << (std::string)*endpoint << std::endl; } http.post_sync( *endpoint, create_zipkin_variant( message, cfg.service_name ), deadline ); consecutive_errors = 0; + return; } catch( const fc::exception& e ) { - wlog( "Unable to connect to zipkin: ${p}, error: ${e}", ("p", cfg.endpoint + cfg.path)("e", e.to_detail_string()) ); + std::cerr << "warn: unable to connect to zipkin: " << (cfg.endpoint + cfg.path) + << ", error: " << e.to_detail_string() << std::endl; } catch( const std::exception& e ) { - wlog( "Unable to connect to zipkin: ${p}, error: ${e}", ("p", cfg.endpoint + cfg.path)("e", e.what()) ); + std::cerr << "warn: unable to connect to zipkin: " << (cfg.endpoint + cfg.path) + << ", error: " << e.what() << std::endl; } catch( ... ) { - wlog( "Unable to connect to zipkin: ${p}, error: ${e}", ("p", cfg.endpoint + cfg.path)("e", "unknown error") ); + std::cerr << "warn: unable to connect to zipkin: " << (cfg.endpoint + cfg.path) + << ", error: unknown" << std::endl; } ++consecutive_errors; } From 02aa7e5963a4c8c6a2fe0b12d99f83dd938854bb Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Fri, 30 Oct 2020 10:47:39 -0500 Subject: [PATCH 055/124] Move over fwd changes --- include/fc/fwd.hpp | 1 + include/fc/fwd_impl.hpp | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/include/fc/fwd.hpp b/include/fc/fwd.hpp index ccf0828e5..d2f794534 100644 --- a/include/fc/fwd.hpp +++ b/include/fc/fwd.hpp @@ -12,6 +12,7 @@ class fwd { public: template fwd( U&& u ); template fwd( U&& u, V&& v ); + template fwd( U&& u, V&& v, X&& ); template fwd( U&& u, V&& v, X&&, Y&& ); fwd(); diff --git a/include/fc/fwd_impl.hpp b/include/fc/fwd_impl.hpp index 639085abe..041e16989 100644 --- a/include/fc/fwd_impl.hpp +++ b/include/fc/fwd_impl.hpp @@ -71,6 +71,12 @@ namespace fc { new (this) T( fc::forward(u), fc::forward(v) ); } template + template + fwd::fwd( U&& u, V&& v, X&& x ) { + check_size(); + new (this) T( fc::forward(u), fc::forward(v), fc::forward(x) ); + } + template template fwd::fwd( U&& u, V&& v, X&& x, Y&& y ) { check_size(); From 588f7bdfed50e5ac9f8f552bdb1a811ad13178c7 Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Fri, 6 Nov 2020 08:30:23 -0600 Subject: [PATCH 056/124] Change zipkin support from being part of fc logging to its own independent util --- CMakeLists.txt | 2 +- include/fc/log/logger_config.hpp | 3 - include/fc/log/trace.hpp | 162 ++-------------------- include/fc/log/zipkin.hpp | 197 +++++++++++++++++++++++++++ include/fc/log/zipkin_appender.hpp | 49 ------- src/log/appender.cpp | 2 - src/log/logger_config.cpp | 23 +--- src/log/zipkin.cpp | 210 +++++++++++++++++++++++++++++ src/log/zipkin_appender.cpp | 176 ------------------------ 9 files changed, 421 insertions(+), 403 deletions(-) create mode 100644 include/fc/log/zipkin.hpp delete mode 100644 include/fc/log/zipkin_appender.hpp create mode 100644 src/log/zipkin.cpp delete mode 100644 src/log/zipkin_appender.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 8117739cf..0ed3b8be4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -111,7 +111,7 @@ set( fc_sources src/compress/smaz.cpp src/compress/zlib.cpp src/log/gelf_appender.cpp - src/log/zipkin_appender.cpp + src/log/zipkin.cpp ) file( GLOB_RECURSE fc_headers ${CMAKE_CURRENT_SOURCE_DIR} *.hpp *.h ) diff --git a/include/fc/log/logger_config.hpp b/include/fc/log/logger_config.hpp index b4e6ae42c..04de647d5 100644 --- a/include/fc/log/logger_config.hpp +++ b/include/fc/log/logger_config.hpp @@ -58,8 +58,6 @@ namespace fc { static bool configure_logging( const logging_config& l ); - static uint64_t get_next_unique_id(); - private: static log_config& get(); @@ -69,7 +67,6 @@ namespace fc { std::unordered_map appender_factory_map; std::unordered_map appender_map; std::unordered_map logger_map; - uint64_t next_id = 0; }; void configure_logging( const fc::path& log_config ); diff --git a/include/fc/log/trace.hpp b/include/fc/log/trace.hpp index c8c3041bf..6a0d3de14 100644 --- a/include/fc/log/trace.hpp +++ b/include/fc/log/trace.hpp @@ -1,177 +1,37 @@ #pragma once -#include -#include -#include +#include #include -#include - -/// Simple wrappers for zipkin tracing, see zipkin_appender -namespace fc { - inline const std::string zipkin_logger_name = "zipkin"; - - struct zipkin_span { - explicit zipkin_span( std::string name, const fc::log_context& lc, uint64_t parent_id = 0 ) - : id( log_config::get_next_unique_id() ) - , parent_id( parent_id ) - , start( time_point::now() ) - , name( std::move(name) ) - , log_context( lc ) - {} - - explicit zipkin_span( uint64_t id, std::string name, const fc::log_context& lc, uint64_t parent_id = 0 ) - : id( id ) - , parent_id( parent_id ) - , start( time_point::now() ) - , name( std::move(name) ) - , log_context( lc ) - {} - - zipkin_span( const zipkin_span& ) = delete; - zipkin_span& operator=( const zipkin_span& ) = delete; - zipkin_span& operator=( zipkin_span&& ) = delete; - - zipkin_span( zipkin_span&& rhs ) noexcept - : id( rhs.id ) - , parent_id( rhs.parent_id ) - , start( rhs.start ) - , name( std::move( rhs.name ) ) - , log_context( std::move( rhs.log_context ) ) - , data( std::move( rhs.data ) ) - { - rhs.id = 0; - } - - ~zipkin_span() { - if( id == 0 ) - return; - try { - auto log = fc::logger::get( zipkin_logger_name ); - if( log.is_enabled( fc::log_level::debug ) ) { - data["zipkin.id"] = id; - static_assert( std::is_same::value, "Expect to store int64_t"); - data["zipkin.timestamp"] = start.time_since_epoch().count(); - static_assert( std::is_same::value, "Expect to store int64_t"); - data["zipkin.duration"] = (time_point::now() - start).count(); - data["zipkin.name"] = std::move(name); - if( parent_id != 0 ) { - data["zipkin.traceId"] = parent_id; - data["zipkin.parentId"] = parent_id; - } else { - data["zipkin.traceId"] = id; - } - log.log( fc::log_message( log_context, "", std::move( data ) ) ); - } - } catch( ... ) {} - } - - void add_tag( const std::string& key, const std::string& var ) { - // zipkin tags are required to be strings - data( key, var ); - } - void add_tag( const std::string& key, const char* var ) { - // zipkin tags are required to be strings - data( key, var ); - } - void add_tag( const std::string& key, bool v ) { - // zipkin tags are required to be strings - data( key, v ? "true" : "false" ); - } - template - std::enable_if_t>, void> - add_tag( const std::string& key, T&& var ) { - data( key, std::to_string( std::forward( var ) ) ); - } - template - std::enable_if_t>, void> - add_tag( const std::string& key, T&& var ) { - data( key, (std::string) var ); - } - - struct token { - friend zipkin_span; - friend struct zipkin_trace; - friend struct optional_trace; - constexpr explicit operator bool() const noexcept { return id != 0; } - private: - explicit token(uint64_t id) - : id(id) {} - uint64_t id; - }; - - token get_token() const { return token{id}; }; - - static uint64_t to_id( const fc::sha256& id ) { - // avoid 0 since id of 0 is used as a flag - return id._hash[3] == 0 ? 1 : id._hash[3]; - } - - template - static uint64_t to_id( const T& id ) { - static_assert( std::is_same_v, "expected uint64_t" ); - return id.data()[3]; - } - - private: - uint64_t id; - // zipkin traceId and parentId are same (when parent_id set) since only allowing trace with span children. - // Not currently supporting spans with children, only trace with children spans. - const uint64_t parent_id; - const fc::time_point start; - std::string name; - fc::log_context log_context; - fc::mutable_variant_object data; - }; - - struct zipkin_trace : public zipkin_span { - using zipkin_span::zipkin_span; - [[nodiscard]] std::optional create_span(std::string name, const fc::log_context& lc) const { - return zipkin_span{ std::move(name), lc, get_token().id }; - } - [[nodiscard]] static std::optional create_span_from_token( zipkin_span::token token, std::string name, const fc::log_context& lc) { - return zipkin_span{ std::move(name), lc, token.id }; - } - }; - - struct optional_trace { - std::optional opt; - constexpr explicit operator bool() const noexcept { return opt.has_value(); } - [[nodiscard]] zipkin_span::token get_token() const { - return opt ? opt->get_token() : zipkin_span::token(0); - } - }; - -} // fc /// @param TRACE_STR const char* identifier for trace /// @return implementation defined type RAII object that submits trace on exit of scope #define fc_create_trace( TRACE_STR ) \ - ::fc::logger::get(::fc::zipkin_logger_name).is_enabled( ::fc::log_level::debug ) ? \ - ::fc::optional_trace{ ::std::optional<::fc::zipkin_trace>( ::std::in_place, (TRACE_STR), FC_LOG_CONTEXT( debug ) ) } \ + ::fc::zipkin_config::is_enabled() ? \ + ::fc::optional_trace{ ::std::optional<::fc::zipkin_trace>( ::std::in_place, (TRACE_STR) ) } \ : ::fc::optional_trace{}; /// @param TRACE_STR const char* identifier for trace /// @param TRACE_ID fc::sha256 id to use /// @return implementation defined type RAII object that submits trace on exit of scope #define fc_create_trace_with_id( TRACE_STR, TRACE_ID ) \ - ::fc::logger::get(::fc::zipkin_logger_name).is_enabled( ::fc::log_level::debug ) ? \ - ::fc::optional_trace{ ::std::optional<::fc::zipkin_trace>( ::std::in_place, ::fc::zipkin_span::to_id(TRACE_ID), (TRACE_STR), FC_LOG_CONTEXT( debug ) ) } \ + ::fc::zipkin_config::is_enabled() ? \ + ::fc::optional_trace{ ::std::optional<::fc::zipkin_trace>( ::std::in_place, ::fc::zipkin_span::to_id(TRACE_ID), (TRACE_STR) ) } \ : ::fc::optional_trace{}; /// @param TRACE_VARNAME variable returned from fc_create_trace /// @param SPAN_STR const char* indentifier /// @return implementation defined type RAII object that submits span on exit of scope #define fc_create_span( TRACE_VARNAME, SPAN_STR ) \ - ( (TRACE_VARNAME) && ::fc::logger::get(::fc::zipkin_logger_name).is_enabled( ::fc::log_level::debug ) ) ? \ - (TRACE_VARNAME).opt->create_span( (SPAN_STR), FC_LOG_CONTEXT( debug ) ) \ + ( (TRACE_VARNAME) && ::fc::zipkin_config::is_enabled() ) ? \ + (TRACE_VARNAME).opt->create_span( (SPAN_STR) ) \ : ::std::optional<::fc::zipkin_span>{}; /// @param TRACE_TOKEN variable returned from trace.get_token() /// @param SPAN_STR const char* indentifier /// @return implementation defined type RAII object that submits span on exit of scope #define fc_create_span_from_token( TRACE_TOKEN, SPAN_STR ) \ - ( (TRACE_TOKEN) && ::fc::logger::get(::fc::zipkin_logger_name).is_enabled( ::fc::log_level::debug ) ) ? \ - ::fc::zipkin_trace::create_span_from_token( (TRACE_TOKEN), (SPAN_STR), FC_LOG_CONTEXT( debug ) ) \ + ( (TRACE_TOKEN) && ::fc::zipkin_config::is_enabled() ) ? \ + ::fc::zipkin_trace::create_span_from_token( (TRACE_TOKEN), (SPAN_STR) ) \ : ::std::optional<::fc::zipkin_span>{}; /// @param SPAN_VARNAME variable returned from fc_create_span @@ -179,6 +39,6 @@ namespace fc { /// @param TAG_VALUE string value #define fc_add_tag( SPAN_VARNAME, TAG_KEY_STR, TAG_VALUE_STR) \ FC_MULTILINE_MACRO_BEGIN \ - if( (SPAN_VARNAME) && ::fc::logger::get(::fc::zipkin_logger_name).is_enabled( ::fc::log_level::debug ) ) \ - (SPAN_VARNAME)->add_tag( (TAG_KEY_STR), (TAG_VALUE_STR) ); \ + if( (SPAN_VARNAME) && ::fc::zipkin_config::is_enabled() ) \ + (SPAN_VARNAME)->add_tag( (TAG_KEY_STR), (TAG_VALUE_STR) ); \ FC_MULTILINE_MACRO_END diff --git a/include/fc/log/zipkin.hpp b/include/fc/log/zipkin.hpp new file mode 100644 index 000000000..2a8a14ad4 --- /dev/null +++ b/include/fc/log/zipkin.hpp @@ -0,0 +1,197 @@ +#pragma once + +#include +#include +#include + +namespace fc { +/// Active Object that sends zipkin messages in JSON format +/// https://zipkin.io/zipkin-api/ +/// +/// Span contains following data +/// uint64_t traceId - unique id for trace, all children spans shared same id +/// std::string name - logical operation, should have low cardinality +/// uint64_t parentId - The parent span id, or absent if root span +/// uint64_t id - unique id for this span +/// int64_t timestamp - epoch microseconds of start of span +/// int64_t duration - microseconds of span +/// +/// Enable zipkin by calling zipkin_config::init() from main thread on startup. +/// Use macros defined in trace.hpp. + +class zipkin; + +class sha256; + +class zipkin_config { +public: + /// Thread safe only if init() called from main thread before spawning of any threads + static bool is_enabled() { return get_zipkin_() != nullptr; } + + /// Not thread safe, call from main thread before spawning any threads that might use zipkin. + /// @param url the url endpoint of zipkin server. e.g. http://127.0.0.1:9411/api/v2/spans + /// @param service_name the service name to include in each zipkin span + /// @param timeout_us the timeout in microseconds for each http call (9 consecutive failures and zipkin is disabled) + static void init( const std::string& url, const std::string& service_name, uint32_t timeout_us ); + + /// Thread safe only if init() called from main thread before spawning of any threads + /// @throw assert_exception if called before init() + static zipkin& get_zipkin(); + + /// Thread safe only if init() called from main thread before spawning of any threads + /// @throw assert_exception if called before init() + static void shutdown(); + + /// Starts with a random id and increments on each call, will not return 0 + static uint64_t get_next_unique_id(); + +private: + /// Provide access to initialized zipkin endpoint + /// Thread safe as long as init() called correctly + /// @return nullptr if init() not called + static zipkin* get_zipkin_() { return get().zip.get(); }; + + static zipkin_config& get(); + +private: + std::unique_ptr zip; +}; + +struct zipkin_span { + explicit zipkin_span( std::string name, uint64_t parent_id = 0 ) + : data( std::move( name ), parent_id ) {} + + explicit zipkin_span( uint64_t id, std::string name, uint64_t parent_id = 0 ) + : data( id, std::move( name ), parent_id ) {} + + zipkin_span( const zipkin_span& ) = delete; + zipkin_span& operator=( const zipkin_span& ) = delete; + zipkin_span& operator=( zipkin_span&& ) = delete; + + zipkin_span( zipkin_span&& rhs ) noexcept + : data( std::move( rhs.data ) ) { + rhs.data.id = 0; + } + + ~zipkin_span(); + + void add_tag( const std::string& key, const std::string& var ) { + // zipkin tags are required to be strings + data.tags( key, var ); + } + + void add_tag( const std::string& key, const char* var ) { + // zipkin tags are required to be strings + data.tags( key, var ); + } + + void add_tag( const std::string& key, bool v ) { + // zipkin tags are required to be strings + data.tags( key, v ? "true" : "false" ); + } + + template + std::enable_if_t>, void> + add_tag( const std::string& key, T&& var ) { + data.tags( key, std::to_string( std::forward( var ) ) ); + } + + template + std::enable_if_t>, void> + add_tag( const std::string& key, T&& var ) { + data.tags( key, (std::string) var ); + } + + struct token { + friend zipkin_span; + friend struct zipkin_trace; + friend struct optional_trace; + constexpr explicit operator bool() const noexcept { return id != 0; } + private: + explicit token( uint64_t id ) + : id( id ) {} + uint64_t id; + }; + + token get_token() const { return token{data.id}; }; + + static uint64_t to_id( const fc::sha256& id ); + + template + static uint64_t to_id( const T& id ) { + static_assert( std::is_same_v, "expected uint64_t" ); + return id.data()[3]; + } + + struct span_data { + explicit span_data( std::string name, uint64_t parent_id = 0 ) + : id( zipkin_config::get_next_unique_id() ), parent_id( parent_id ), + start( time_point::now() ), name( std::move( name ) ) {} + + explicit span_data( uint64_t id, std::string name, uint64_t parent_id = 0 ) + : id( id ), parent_id( parent_id ), start( time_point::now() ), name( std::move( name ) ) {} + + span_data( const span_data& ) = delete; + span_data& operator=( const span_data& ) = delete; + span_data& operator=( span_data&& ) = delete; + span_data( span_data&& rhs ) noexcept = default; + + uint64_t id; + // zipkin traceId and parentId are same (when parent_id set) since only allowing trace with span children. + // Not currently supporting spans with children, only trace with children spans. + const uint64_t parent_id; + const fc::time_point start; + fc::time_point stop; + std::string name; + fc::mutable_variant_object tags; + }; + + span_data data; +}; + +struct zipkin_trace : public zipkin_span { + using zipkin_span::zipkin_span; + + [[nodiscard]] std::optional create_span( std::string name ) const { + return zipkin_span{std::move( name ), get_token().id}; + } + + [[nodiscard]] static std::optional + create_span_from_token( zipkin_span::token token, std::string name ) { + return zipkin_span{std::move( name ), token.id}; + } +}; + +struct optional_trace { + std::optional opt; + + constexpr explicit operator bool() const noexcept { return opt.has_value(); } + + [[nodiscard]] zipkin_span::token get_token() const { + return opt ? opt->get_token() : zipkin_span::token( 0 ); + } +}; + +class zipkin { +public: + zipkin( const std::string& url, const std::string& service_name, uint32_t timeout_us ); + + /// finishes logging all queued up spans + ~zipkin() = default; + + /// Starts with a random id and increments on each call, will not return 0 + uint64_t get_next_unique_id(); + + // finish logging all queued up spans, not restartable + void shutdown(); + + // Logs zipkin json via http on separate thread + void log( zipkin_span::span_data&& span ); + +private: + class impl; + std::unique_ptr my; +}; + +} // namespace fc + diff --git a/include/fc/log/zipkin_appender.hpp b/include/fc/log/zipkin_appender.hpp deleted file mode 100644 index 293c99b9b..000000000 --- a/include/fc/log/zipkin_appender.hpp +++ /dev/null @@ -1,49 +0,0 @@ -#pragma once - -#include -#include -#include - -namespace fc -{ - // Active Log appender that sends zipkin messages in JSON format - // https://zipkin.io/zipkin-api/ - // - // log_message should contain following variant data - // uint64_t zipkin.traceId - unique id for trace, all children spans shared same id - // std::string zipkin.name - logical operation, should have low cardinality - // uint64_t zipkin.parentId - The parent span id, or absent if root span - // uint64_t zipkin.id - unique if for this span - // int64_t zipkin.timestamp - epoch microseconds of start of span - // int64_t zipkin.duration - microseconds of span - - class zipkin_appender final : public appender { - public: - struct config { - std::string endpoint = "http://127.0.0.1:9411"; - std::string path = "/api/v2/spans"; // path to post span - std::string service_name = "unknown"; // localEndpoint.serviceName reported on each Span - uint32_t timeout_us = 200*1000; // 200ms - }; - - explicit zipkin_appender( const variant& args ); - ~zipkin_appender() = default; - - // no-op. connection made on first log() - void initialize( boost::asio::io_service& io_service ) override; - - // finish logging all queued up spans - void shutdown() override; - - // Logs zipkin json via http on separate thread - void log( const log_message& m ) override; - - private: - class impl; - std::shared_ptr my; - }; -} // namespace fc - -#include -FC_REFLECT( fc::zipkin_appender::config, - (endpoint)(path)(service_name)(timeout_us) ) diff --git a/src/log/appender.cpp b/src/log/appender.cpp index 9c1038cd9..d6ca52805 100644 --- a/src/log/appender.cpp +++ b/src/log/appender.cpp @@ -2,7 +2,6 @@ #include #include #include -#include #include @@ -11,6 +10,5 @@ namespace fc { static bool reg_console_appender = log_config::register_appender( "console" ); static bool reg_gelf_appender = log_config::register_appender( "gelf" ); static bool reg_dmlog_appender = log_config::register_appender( "dmlog" ); - static bool reg_zipkin_appender = log_config::register_appender( "zipkin" ); } // namespace fc diff --git a/src/log/logger_config.cpp b/src/log/logger_config.cpp index 3372e153f..6d8484362 100644 --- a/src/log/logger_config.cpp +++ b/src/log/logger_config.cpp @@ -7,10 +7,8 @@ #include #include #include -#include #include #include -#include namespace fc { @@ -27,18 +25,6 @@ namespace fc { return true; } - uint64_t log_config::get_next_unique_id() { - auto& lc = log_config::get(); - std::lock_guard g( lc.log_mutex ); - if( lc.next_id == 0 ) { - std::mt19937_64 engine( std::random_device{}() ); - std::uniform_int_distribution distribution(1); - lc.next_id = distribution( engine ); - } - return lc.next_id++; - } - - logger log_config::get_logger( const fc::string& name ) { std::lock_guard g( log_config::get().log_mutex ); return log_config::get().logger_map[name]; @@ -75,7 +61,6 @@ namespace fc { static bool reg_console_appender = log_config::register_appender( "console" ); static bool reg_gelf_appender = log_config::register_appender( "gelf" ); static bool reg_dmlog_appender = log_config::register_appender( "dmlog" ); - static bool reg_zipkin_appender = log_config::register_appender( "zipkin" ); std::lock_guard g( log_config::get().log_mutex ); log_config::get().logger_map.clear(); @@ -105,15 +90,11 @@ namespace fc { for( auto a = cfg.loggers[i].appenders.begin(); a != cfg.loggers[i].appenders.end(); ++a ){ auto ap_it = log_config::get().appender_map.find(*a); if( ap_it != log_config::get().appender_map.end() ) { - if( lgr.name() == DEFAULT_LOGGER && (dynamic_cast(ap_it->second.get()) != nullptr) ) { - std::cerr << "warn: zipkin_appender not allowed for default logger" << std::endl; - } else { - lgr.add_appender( ap_it->second ); - } + lgr.add_appender( ap_it->second ); } } } - return reg_console_appender || reg_gelf_appender || reg_dmlog_appender || reg_zipkin_appender; + return reg_console_appender || reg_gelf_appender || reg_dmlog_appender; } catch ( exception& e ) { std::cerr< +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +namespace fc { + +zipkin_config& zipkin_config::get() { + static zipkin_config the_one; + return the_one; +} + +void zipkin_config::init( const std::string& url, const std::string& service_name, uint32_t timeout_us ) { + get().zip = std::make_unique( url, service_name, timeout_us ); +} + +zipkin& zipkin_config::get_zipkin() { + if( !get().zip ) { + FC_THROW_EXCEPTION( fc::assert_exception, "uninitialized zipkin" ); + } + return *get().zip; +} + +void zipkin_config::shutdown() { + if( zipkin* z = get_zipkin_() ) { + z->shutdown(); + } +} + +uint64_t zipkin_config::get_next_unique_id() { + if( !get().zip ) { + FC_THROW_EXCEPTION( fc::assert_exception, "uninitialized zipkin" ); + } + return get().zip->get_next_unique_id(); +} + +class zipkin::impl { +public: + static constexpr uint32_t max_consecutive_errors = 9; + + const std::string zipkin_url; + const std::string service_name; + const uint32_t timeout_us; + std::mutex mtx; + uint64_t next_id = 0; + http_client http; + std::atomic consecutive_errors = 0; + std::atomic stopped = 0; + std::optional endpoint; + std::thread thread; + boost::asio::io_context ctx; + boost::asio::strand work_strand = boost::asio::make_strand(ctx); + boost::asio::executor_work_guard work_guard = boost::asio::make_work_guard(ctx); + + impl( std::string url, std::string service_name, uint32_t timeout_us ) + : zipkin_url( std::move(url) ) + , service_name( std::move(service_name) ) + , timeout_us( timeout_us ) { + } + + void init(); + void shutdown(); + + void log( zipkin_span::span_data&& span ); + + ~impl(); +}; + +void zipkin::impl::init() { + thread = std::thread( [this]() { + fc::set_os_thread_name( "zipkin" ); + while( true ) { + try { + ctx.run(); + break; + } FC_LOG_AND_DROP(); + } + } ); +} + +zipkin::impl::~impl() { + try { + shutdown(); + } catch (...) {} +} + +void zipkin::impl::shutdown() { + if( stopped ^= 1 ) return; + work_guard.reset(); // drain the queue + thread.join(); +} + +zipkin::zipkin( const std::string& url, const std::string& service_name, uint32_t timeout_us ) : + my( new impl( url, service_name, timeout_us ) ) { + my->init(); +} + +uint64_t zipkin::get_next_unique_id() { + std::scoped_lock g( my->mtx ); + if( my->next_id == 0 ) { + std::mt19937_64 engine( std::random_device{}() ); + std::uniform_int_distribution distribution(1); + my->next_id = distribution( engine ); + } + return my->next_id++; +} + +void zipkin::shutdown() { + my->shutdown(); +} + +fc::variant create_zipkin_variant( zipkin_span::span_data&& span, const std::string& service_name ) { + // https://zipkin.io/zipkin-api/ + // std::string traceId; // [a-f0-9]{16,32} unique id for trace, all children spans shared same id + // std::string name; // logical operation, should have low cardinality + // std::string parentId; // The parent span id, or absent if root span + // std::string id // a-f0-9]{16} + // int64_t timestamp // epoch microseconds of start of span + // int64_t duration // microseconds of span + + uint64_t trace_id; + if( span.parent_id != 0 ) { + trace_id = span.parent_id; + } else { + trace_id = span.id; + } + + fc::mutable_variant_object mvo; + mvo( "id", fc::to_hex( reinterpret_cast(&span.id), sizeof( span.id ) ) ); + mvo( "traceId", fc::to_hex( reinterpret_cast(&trace_id), sizeof( trace_id ) ) ); + if( span.parent_id != 0 ) { + mvo( "parentId", fc::to_hex( reinterpret_cast(&span.parent_id), sizeof( span.parent_id ) ) ); + } + mvo( "name", std::move( span.name ) ); + mvo( "timestamp", span.start.time_since_epoch().count() ); + mvo( "duration", (span.stop - span.start).count() ); + mvo( "localEndpoint", fc::variant_object( "serviceName", service_name ) ); + + mvo( "tags", std::move( span.tags ) ); + span.id = 0; // stop destructor of span from calling log again + + // /api/v2/spans takes an array of spans + fc::variants result; + result.emplace_back( std::move( mvo ) ); + + return result; +} + +void zipkin::log( zipkin_span::span_data&& span ) { + if( my->consecutive_errors > my->max_consecutive_errors || my->stopped ) + return; + + boost::asio::post(my->work_strand, [this, span{std::move(span)}]() mutable { + my->log( std::move( span ) ); + }); +} + +void zipkin::impl::log( zipkin_span::span_data&& span ) { + if( consecutive_errors > max_consecutive_errors ) + return; + + try { + auto deadline = fc::time_point::now() + fc::microseconds( timeout_us ); + if( !endpoint ) { + endpoint = url( zipkin_url ); + dlog( "connecting to zipkin: ${p}", ("p", *endpoint) ); + } + + http.post_sync( *endpoint, create_zipkin_variant( std::move( span ), service_name ), deadline ); + + consecutive_errors = 0; + return; + } catch( const fc::exception& e ) { + wlog( "unable to connect to zipkin: ${u}, error: ${e}", ("u", zipkin_url)("e", e.to_detail_string()) ); + } catch( const std::exception& e ) { + wlog( "unable to connect to zipkin: ${u}, error: ${e}", ("u", zipkin_url)("e", e.what()) ); + } catch( ... ) { + wlog( "unable to connect to zipkin: ${u}, error: unknown", ("u", zipkin_url) ); + } + ++consecutive_errors; +} + +uint64_t zipkin_span::to_id( const fc::sha256& id ) { + // avoid 0 since id of 0 is used as a flag + return id._hash[3] == 0 ? 1 : id._hash[3]; +} + +zipkin_span::~zipkin_span() { + if( data.id == 0 ) + return; + try { + if( zipkin_config::is_enabled() ) { + data.stop = time_point::now(); + zipkin_config::get_zipkin().log( std::move( data ) ); + } + } catch( ... ) {} +} + + + +} // fc diff --git a/src/log/zipkin_appender.cpp b/src/log/zipkin_appender.cpp deleted file mode 100644 index 36b6ec4ab..000000000 --- a/src/log/zipkin_appender.cpp +++ /dev/null @@ -1,176 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -namespace fc { - -class zipkin_appender::impl { -public: - static constexpr uint32_t max_consecutive_errors = 9; - - config cfg; - http_client http; - std::atomic consecutive_errors = 0; - std::optional endpoint; - std::thread thread; - boost::asio::io_context ctx; - boost::asio::strand work_strand = boost::asio::make_strand(ctx); - boost::asio::executor_work_guard work_guard = boost::asio::make_work_guard(ctx); - - explicit impl( config c ) : - cfg( std::move( c ) ) { - } - - void init(); - - void log( const log_message& message ); - - ~impl(); -}; - -void zipkin_appender::impl::init() { - thread = std::thread( [this]() { - fc::set_os_thread_name( "zipkin" ); - while( true ) { - try { - ctx.run(); - break; - } FC_LOG_AND_DROP(); - } - } ); -} - -zipkin_appender::impl::~impl() { - try { - work_guard.reset(); // drain the queue - thread.join(); - } catch (...) {} -} - -zipkin_appender::zipkin_appender( const variant& args ) : - my( new impl( args.as() ) ) { -} - -void zipkin_appender::initialize( boost::asio::io_service& io_service ) { - // called holding the log_config log_mutex - if( my ) - my->init(); -} - -void zipkin_appender::shutdown() { - // called holding the log_config log_mutex - my.reset(); -} - -fc::variant create_zipkin_variant( const log_message& message, const std::string& service_name ) { - // https://zipkin.io/zipkin-api/ - // std::string traceId; // [a-f0-9]{16,32} unique id for trace, all children spans shared same id - // std::string name; // logical operation, should have low cardinality - // std::string parentId; // The parent span id, or absent if root span - // std::string id // a-f0-9]{16} - // int64_t timestamp // epoch microseconds of start of span - // int64_t duration // microseconds of span - - log_context context = message.get_context(); - fc::mutable_variant_object d = message.get_data(); - - fc::mutable_variant_object mvo; - auto i = d.find( "zipkin.traceId" ); - if( i != d.end() && i->value().is_uint64() ) { - uint64_t v = i->value().as_uint64(); - mvo( "traceId", fc::to_hex( reinterpret_cast(&v), sizeof( v ) ) ); - d.erase( "zipkin.traceId" ); - } else { - FC_THROW_EXCEPTION( parse_error_exception, "zipkin.traceId required" ); - } - i = d.find( "zipkin.id" ); - if( i != d.end() && i->value().is_uint64() ) { - uint64_t v = i->value().as_uint64(); - mvo( "id", fc::to_hex( reinterpret_cast(&v), sizeof( v ) ) ); - d.erase( "zipkin.id" ); - } else { - FC_THROW_EXCEPTION( parse_error_exception, "zipkin.id required" ); - } - i = d.find( "zipkin.parentId" ); - if( i != d.end() && i->value().is_uint64() ) { - uint64_t v = i->value().as_uint64(); - if( v != 0 ) - mvo( "parentId", fc::to_hex( reinterpret_cast(&v), sizeof( v ) ) ); - d.erase( "zipkin.parentId" ); - } - i = d.find( "zipkin.name" ); - if( i != d.end() ) { - mvo( "name", i->value() ); - d.erase( "zipkin.name" ); - } - i = d.find( "zipkin.timestamp" ); - if( i != d.end() ) { - mvo( "timestamp", i->value() ); - d.erase( "zipkin.timestamp" ); - } - i = d.find( "zipkin.duration" ); - if( i != d.end() ) { - mvo( "duration", i->value() ); - d.erase( "zipkin.duration" ); - } - - mvo( "localEndpoint", fc::variant_object( "serviceName", service_name ) ); - - mvo( "tags", d ); - - // /api/v2/spans takes an array of spans - fc::variants result; - result.emplace_back( mvo ); - - return result; -} - -void zipkin_appender::log( const log_message& message ) { - // called holding the log_config log_mutex - if( !my || my->consecutive_errors > my->max_consecutive_errors ) - return; - - boost::asio::post(my->work_strand, [this, message]() { - my->log( message ); - }); -} - -void zipkin_appender::impl::log( const log_message& message ) { - if( consecutive_errors > max_consecutive_errors ) - return; - - try { - auto deadline = fc::time_point::now() + fc::microseconds( cfg.timeout_us ); - if( !endpoint ) { - endpoint = url( cfg.endpoint + cfg.path ); - std::cout << "info: connecting to zipkin: " << (std::string)*endpoint << std::endl; - } - - http.post_sync( *endpoint, create_zipkin_variant( message, cfg.service_name ), deadline ); - - consecutive_errors = 0; - return; - } catch( const fc::exception& e ) { - std::cerr << "warn: unable to connect to zipkin: " << (cfg.endpoint + cfg.path) - << ", error: " << e.to_detail_string() << std::endl; - } catch( const std::exception& e ) { - std::cerr << "warn: unable to connect to zipkin: " << (cfg.endpoint + cfg.path) - << ", error: " << e.what() << std::endl; - } catch( ... ) { - std::cerr << "warn: unable to connect to zipkin: " << (cfg.endpoint + cfg.path) - << ", error: unknown" << std::endl; - } - ++consecutive_errors; -} - -} // fc From 40313ca3e3cdabb1d9cac389fbb2288d3fea834c Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Fri, 6 Nov 2020 10:35:26 -0600 Subject: [PATCH 057/124] Fix default move constructor --- include/fc/log/zipkin.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/fc/log/zipkin.hpp b/include/fc/log/zipkin.hpp index 2a8a14ad4..32010a114 100644 --- a/include/fc/log/zipkin.hpp +++ b/include/fc/log/zipkin.hpp @@ -134,7 +134,7 @@ struct zipkin_span { span_data( const span_data& ) = delete; span_data& operator=( const span_data& ) = delete; span_data& operator=( span_data&& ) = delete; - span_data( span_data&& rhs ) noexcept = default; + span_data( span_data&& rhs ) = default; uint64_t id; // zipkin traceId and parentId are same (when parent_id set) since only allowing trace with span children. From ef15c08a33e0747e4ec522b0f05b29c1a06ea35c Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Fri, 6 Nov 2020 12:21:43 -0600 Subject: [PATCH 058/124] Remove dead code --- include/fc/log/logger.hpp | 2 -- src/log/appender.cpp | 1 + src/log/logger.cpp | 16 ---------------- 3 files changed, 1 insertion(+), 18 deletions(-) diff --git a/include/fc/log/logger.hpp b/include/fc/log/logger.hpp index 509282590..803a2de0a 100644 --- a/include/fc/log/logger.hpp +++ b/include/fc/log/logger.hpp @@ -50,8 +50,6 @@ namespace fc bool is_enabled( log_level e )const; void log( log_message m ); - void shutdown(); - private: friend struct log_config; void add_appender( const std::shared_ptr& a ); diff --git a/src/log/appender.cpp b/src/log/appender.cpp index d6ca52805..b04244272 100644 --- a/src/log/appender.cpp +++ b/src/log/appender.cpp @@ -11,4 +11,5 @@ namespace fc { static bool reg_gelf_appender = log_config::register_appender( "gelf" ); static bool reg_dmlog_appender = log_config::register_appender( "dmlog" ); + } // namespace fc diff --git a/src/log/logger.cpp b/src/log/logger.cpp index bf88729d6..edc029c34 100644 --- a/src/log/logger.cpp +++ b/src/log/logger.cpp @@ -82,22 +82,6 @@ namespace fc { } } - void logger::shutdown() { - std::unique_lock g( log_config::get().log_mutex ); - - for( auto& a : my->_appenders ) { - try { - a->shutdown(); - } catch( fc::exception& er ) { - std::cerr << "ERROR: logger::shutdown fc::exception: " << er.to_detail_string() << std::endl; - } catch( const std::exception& e ) { - std::cerr << "ERROR: logger::shutdown std::exception: " << e.what() << std::endl; - } catch( ... ) { - std::cerr << "ERROR: logger::shutdown unknown exception: " << std::endl; - } - } - } - void logger::set_name( const fc::string& n ) { my->_name = n; } const fc::string& logger::name()const { return my->_name; } From bfed8803e8964c967c7fbf317dc5a8c65bd32ad4 Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Fri, 6 Nov 2020 12:23:21 -0600 Subject: [PATCH 059/124] Remove dead code --- include/fc/log/appender.hpp | 1 - src/log/zipkin.cpp | 2 -- 2 files changed, 3 deletions(-) diff --git a/include/fc/log/appender.hpp b/include/fc/log/appender.hpp index 87db64c33..c01aadb0e 100644 --- a/include/fc/log/appender.hpp +++ b/include/fc/log/appender.hpp @@ -37,7 +37,6 @@ namespace fc { typedef std::shared_ptr ptr; virtual void initialize( boost::asio::io_service& io_service ) = 0; - virtual void shutdown() {} virtual void log( const log_message& m ) = 0; }; } diff --git a/src/log/zipkin.cpp b/src/log/zipkin.cpp index f9845bfec..b816a8b3f 100644 --- a/src/log/zipkin.cpp +++ b/src/log/zipkin.cpp @@ -205,6 +205,4 @@ zipkin_span::~zipkin_span() { } catch( ... ) {} } - - } // fc From 99e1555e49d42c7e38ecc72b1802a33b839bfa1d Mon Sep 17 00:00:00 2001 From: allen han Date: Tue, 10 Nov 2020 13:33:56 -0600 Subject: [PATCH 060/124] add reason to error msg in copy --- src/filesystem.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/filesystem.cpp b/src/filesystem.cpp index 1b8df2018..1d5075747 100644 --- a/src/filesystem.cpp +++ b/src/filesystem.cpp @@ -256,8 +256,8 @@ namespace fc { ("srcfile",f)("dstfile",t)("inner", fc::except_str() ) ); } if( ec ) { - FC_THROW( "Copy from ${srcfile} to ${dstfile} failed because ${reason}", - ("srcfile",f)("dstfile",t)("reason", ec.category().name() ) ); + FC_THROW( "Copy from ${srcfile} to ${dstfile} failed because ${reason}, category: ${cat}", + ("srcfile",f)("dstfile",t)("reason", ec.message())("cat", ec.category().name()) ); } } void resize_file( const path& f, size_t t ) From 1fe648d0acc6b358551bae544aace18853700940 Mon Sep 17 00:00:00 2001 From: allen han Date: Mon, 16 Nov 2020 13:38:55 -0600 Subject: [PATCH 061/124] use none recursive for boost version > 74 --- src/filesystem.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/filesystem.cpp b/src/filesystem.cpp index 1b8df2018..d9e66b70e 100644 --- a/src/filesystem.cpp +++ b/src/filesystem.cpp @@ -247,7 +247,14 @@ namespace fc { void copy( const path& f, const path& t ) { boost::system::error_code ec; try { + #if (BOOST_VERSION/100000) == 1 && ((BOOST_VERSION/100)%1000) > 73 + boost::filesystem::copy( boost::filesystem::path(f), + boost::filesystem::path(t), + boost::filesystem::copy_options::directories_only, + ec ); + #else boost::filesystem::copy( boost::filesystem::path(f), boost::filesystem::path(t), ec ); + #endif } catch ( boost::system::system_error& e ) { FC_THROW( "Copy from ${srcfile} to ${dstfile} failed because ${reason}", ("srcfile",f)("dstfile",t)("reason",e.what() ) ); From 0643a877e3543810d6909f191c63c799e7f57b4a Mon Sep 17 00:00:00 2001 From: Matt Witherspoon <32485495+spoonincode@users.noreply.github.com> Date: Mon, 16 Nov 2020 14:52:31 -0500 Subject: [PATCH 062/124] avoid make_strand() as it's a boost 1.70 feature --- src/log/zipkin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/log/zipkin.cpp b/src/log/zipkin.cpp index b816a8b3f..eddf4d41d 100644 --- a/src/log/zipkin.cpp +++ b/src/log/zipkin.cpp @@ -58,7 +58,7 @@ class zipkin::impl { std::optional endpoint; std::thread thread; boost::asio::io_context ctx; - boost::asio::strand work_strand = boost::asio::make_strand(ctx); + boost::asio::io_context::strand work_strand{ctx}; boost::asio::executor_work_guard work_guard = boost::asio::make_work_guard(ctx); impl( std::string url, std::string service_name, uint32_t timeout_us ) From 46972483ef9a897d5da59820456a66fef6fa4c67 Mon Sep 17 00:00:00 2001 From: allen han Date: Tue, 17 Nov 2020 13:39:12 -0600 Subject: [PATCH 063/124] Add test cases for copy file and dir --- test/CMakeLists.txt | 5 +++ test/test_filesystem.cpp | 95 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 100 insertions(+) create mode 100644 test/test_filesystem.cpp diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 4d6c4bb3e..8d292ed67 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -9,3 +9,8 @@ add_executable( test_base64 test_base64.cpp ) target_link_libraries( test_base64 fc ) add_test(NAME test_base64 COMMAND libraries/fc/test/test_base64 WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) + +add_executable( test_filesystem test_filesystem.cpp ) +target_link_libraries( test_filesystem fc ) + +add_test(NAME test_filesystem COMMAND libraries/fc/test/test_filesystem WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) diff --git a/test/test_filesystem.cpp b/test/test_filesystem.cpp new file mode 100644 index 000000000..6f9804732 --- /dev/null +++ b/test/test_filesystem.cpp @@ -0,0 +1,95 @@ +#define BOOST_TEST_MODULE fc_filesystem +#include +#include +#include +#include + +using namespace fc; + +std::string getFileContent(const string& filename) { + string ret; + boost::filesystem::ifstream ifs { filename }; + ifs >> ret; + ifs.close(); + return ret; +} + +BOOST_AUTO_TEST_SUITE(fc_filesystem) + +BOOST_AUTO_TEST_CASE(dir_copy) try { + // 1. check whether dir can be copied when target dir does not exist, + // but not recursively (compatible with 1.73) + + const string src_dir {"/tmp/fc_copy_test_src"}; + if (!fc::exists(src_dir)) { + create_directories(src_dir); + } + + BOOST_CHECK_EQUAL(fc::exists(src_dir), true); + const string test_file_name = "fc_copy_test_file"; + if (!fc::exists(src_dir + "/" + test_file_name)) { + boost::filesystem::ofstream ofs { src_dir + "/" + test_file_name}; + ofs << "This the test of fc system copy \n"; + ofs.close(); + } + BOOST_CHECK_EQUAL(fc::exists(src_dir + "/" + test_file_name), true); + + const string tgt_dir {"/tmp/fc_copy_test_tgt"}; + if (fc::exists(tgt_dir)) { + remove_all(tgt_dir); + } + BOOST_CHECK_EQUAL(fc::exists(tgt_dir), false); + + fc::copy(src_dir, tgt_dir); + BOOST_CHECK_EQUAL(fc::exists(tgt_dir), true); + // check not copied recursively + BOOST_CHECK_EQUAL(fc::exists(tgt_dir + "/" + test_file_name), false); + + // 2. check whether exception be thrown (no overwrite) when target dir does exist, + BOOST_CHECK_EQUAL(fc::exists(tgt_dir), true); + BOOST_CHECK_EXCEPTION(fc::copy(src_dir, tgt_dir), fc::exception, [](const fc::exception& e) { + return e.code() == fc::unspecified_exception_code; + }); + +} FC_LOG_AND_RETHROW(); + +BOOST_AUTO_TEST_CASE(file_copy) try { + // 1. check whether file can be copied when target file does not exist, + const string src_dir {"/tmp/fc_copy_test_src"}; + if (!fc::exists(src_dir)) { + create_directories(src_dir); + } + + BOOST_CHECK_EQUAL(fc::exists(src_dir), true); + const string test_file_name = "fc_copy_test_file"; + if (!fc::exists(src_dir + "/" + test_file_name)) { + boost::filesystem::ofstream ofs { src_dir + "/" + test_file_name}; + ofs << "This the test of fc system copy \n"; + ofs.close(); + } + BOOST_CHECK_EQUAL(fc::exists(src_dir + "/" + test_file_name), true); + + const string tgt_dir {"/tmp/fc_copy_test_tgt"}; + if (!fc::exists(tgt_dir)) { + fc::copy(src_dir, tgt_dir); + } + BOOST_CHECK_EQUAL(fc::exists(tgt_dir), true); + BOOST_CHECK_EQUAL(fc::exists(tgt_dir + "/" + test_file_name), false); + fc::copy(src_dir + "/" + test_file_name, tgt_dir + "/" + test_file_name); + BOOST_CHECK_EQUAL(fc::exists(tgt_dir + "/" + test_file_name), true); + const string src_file_content = getFileContent(src_dir + "/" + test_file_name); + BOOST_CHECK_EQUAL(src_file_content.empty(), false); + const string tgt_file_content = getFileContent(tgt_dir + "/" + test_file_name); + BOOST_CHECK_EQUAL(src_file_content, tgt_file_content); + + // 2. check whether exception be thrown (no overwrite) when target file does exist, + BOOST_CHECK_EQUAL(fc::exists(tgt_dir + "/" + test_file_name), true); + BOOST_CHECK_EXCEPTION(fc::copy(src_dir + "/" + test_file_name, tgt_dir + "/" + test_file_name), + fc::exception, + [](const fc::exception& e) { + return e.code() == fc::unspecified_exception_code; + }); + +} FC_LOG_AND_RETHROW(); + +BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file From 97479bb85bd065b9d16d03a8047e51f94327440a Mon Sep 17 00:00:00 2001 From: Yue Han Date: Tue, 17 Nov 2020 15:05:21 -0600 Subject: [PATCH 064/124] Add change for 1.74 --- src/filesystem.cpp | 18 ++++++++++++++---- test/test_filesystem.cpp | 4 ++-- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/filesystem.cpp b/src/filesystem.cpp index d9e66b70e..65b23d5f6 100644 --- a/src/filesystem.cpp +++ b/src/filesystem.cpp @@ -248,10 +248,20 @@ namespace fc { boost::system::error_code ec; try { #if (BOOST_VERSION/100000) == 1 && ((BOOST_VERSION/100)%1000) > 73 - boost::filesystem::copy( boost::filesystem::path(f), - boost::filesystem::path(t), - boost::filesystem::copy_options::directories_only, - ec ); + if (exists(t)){ + throw boost::system::system_error(boost::system::errc::make_error_code(boost::system::errc::errc_t::file_exists)); + } + if ( boost::filesystem::is_directory( f ) ) { + boost::filesystem::copy(boost::filesystem::path(f), + boost::filesystem::path(t), + boost::filesystem::copy_options::directories_only, + ec ); + } else { + boost::filesystem::copy(boost::filesystem::path(f), + boost::filesystem::path(t), + boost::filesystem::copy_options::none, + ec ); + } #else boost::filesystem::copy( boost::filesystem::path(f), boost::filesystem::path(t), ec ); #endif diff --git a/test/test_filesystem.cpp b/test/test_filesystem.cpp index 6f9804732..53020171a 100644 --- a/test/test_filesystem.cpp +++ b/test/test_filesystem.cpp @@ -45,7 +45,7 @@ BOOST_AUTO_TEST_CASE(dir_copy) try { // check not copied recursively BOOST_CHECK_EQUAL(fc::exists(tgt_dir + "/" + test_file_name), false); - // 2. check whether exception be thrown (no overwrite) when target dir does exist, + // 2. check whether exception be thrown (no overwritten) when target dir does exist, BOOST_CHECK_EQUAL(fc::exists(tgt_dir), true); BOOST_CHECK_EXCEPTION(fc::copy(src_dir, tgt_dir), fc::exception, [](const fc::exception& e) { return e.code() == fc::unspecified_exception_code; @@ -82,7 +82,7 @@ BOOST_AUTO_TEST_CASE(file_copy) try { const string tgt_file_content = getFileContent(tgt_dir + "/" + test_file_name); BOOST_CHECK_EQUAL(src_file_content, tgt_file_content); - // 2. check whether exception be thrown (no overwrite) when target file does exist, + // 2. check whether exception be thrown (no overwritten) when target file does exist, BOOST_CHECK_EQUAL(fc::exists(tgt_dir + "/" + test_file_name), true); BOOST_CHECK_EXCEPTION(fc::copy(src_dir + "/" + test_file_name, tgt_dir + "/" + test_file_name), fc::exception, From 13ce5a7978a7c8caf01609ee751c97f34a713dd3 Mon Sep 17 00:00:00 2001 From: allen han Date: Wed, 18 Nov 2020 11:44:54 -0600 Subject: [PATCH 065/124] update the boost version check --- src/filesystem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/filesystem.cpp b/src/filesystem.cpp index 65b23d5f6..51dee6a6b 100644 --- a/src/filesystem.cpp +++ b/src/filesystem.cpp @@ -247,7 +247,7 @@ namespace fc { void copy( const path& f, const path& t ) { boost::system::error_code ec; try { - #if (BOOST_VERSION/100000) == 1 && ((BOOST_VERSION/100)%1000) > 73 + #if BOOST_VERSION > 107300 if (exists(t)){ throw boost::system::system_error(boost::system::errc::make_error_code(boost::system::errc::errc_t::file_exists)); } From 8737e6a06afb17e033c50e9ecd5bc814f8b4b260 Mon Sep 17 00:00:00 2001 From: Timothy Banks Date: Tue, 22 Dec 2020 18:14:52 -0500 Subject: [PATCH 066/124] Ignore unused const variable. --- src/crypto/crc.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/crypto/crc.cpp b/src/crypto/crc.cpp index 3b9545503..2467840c5 100644 --- a/src/crypto/crc.cpp +++ b/src/crypto/crc.cpp @@ -515,6 +515,9 @@ uint32_t crc32cSlicingBy8(uint32_t crc, const void* data, size_t length) { #define CRC32C_POLY 0x1EDC6F41 +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-const-variable" + #define CRC32C(c,d) (c=(c>>8)^crc_c[(c^(d))&0xFF]) /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Copyright 2001, D. Otis. Use this program, code or tables */ @@ -601,6 +604,9 @@ static const uint32_t crc_c[256] = { 0x79B737BA, 0x8BDCB4B9, 0x988C474D, 0x6AE7C44E, 0xBE2DA0A5, 0x4C4623A6, 0x5F16D052, 0xAD7D5351, }; + +#pragma GCC diagnostic pop + #if !defined __SSE4_2__ || (defined __SSE4_2__ && !defined __x86_64__) From fd621b6d6451d58f15977e2277225636fcdbf1ae Mon Sep 17 00:00:00 2001 From: Timothy Banks Date: Tue, 22 Dec 2020 21:51:57 -0500 Subject: [PATCH 067/124] Inhibit warning messages for 3rdParty libraries --- CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0ed3b8be4..5408c3d88 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,7 +25,10 @@ elseif(NOT CMAKE_CXX_STANDARD) set(CMAKE_CXX_STANDARD_REQUIRED ON) endif() +# Suppress warnings on 3rdParty Library +add_definitions( -w ) add_subdirectory( secp256k1 ) +remove_definitions( -w ) IF( ECC_IMPL STREQUAL openssl ) SET( ECC_REST src/crypto/elliptic_impl_pub.cpp ) From 251bcf9d390bbeb2864ea92351e806265ac5ad62 Mon Sep 17 00:00:00 2001 From: Matt Witherspoon <32485495+spoonincode@users.noreply.github.com> Date: Wed, 16 Dec 2020 17:31:09 -0500 Subject: [PATCH 068/124] replace old libsecp256k1 fork with upstream --- .gitmodules | 6 +- include/fc/crypto/elliptic.hpp | 40 ----- include/fc/crypto/elliptic_r1.hpp | 1 - secp256k1/CMakeLists.txt | 10 +- .../config_with_gmp/libsecp256k1-config.h | 12 +- .../config_without_gmp/libsecp256k1-config.h | 12 +- secp256k1/secp256k1 | 1 + secp256k1/upstream | 1 - src/crypto/_elliptic_impl_priv.hpp | 2 +- src/crypto/elliptic_common.cpp | 9 -- src/crypto/elliptic_impl_priv.cpp | 20 ++- src/crypto/elliptic_r1.cpp | 9 -- src/crypto/elliptic_secp256k1.cpp | 147 +++--------------- 13 files changed, 51 insertions(+), 219 deletions(-) create mode 160000 secp256k1/secp256k1 delete mode 160000 secp256k1/upstream diff --git a/.gitmodules b/.gitmodules index 14ad7b178..2ff5eb9c0 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,6 @@ -[submodule "secp256k1/upstream"] - path = secp256k1/upstream - url = https://github.com/cryptonomex/secp256k1-zkp.git [submodule "include/fc/crypto/webauthn_json"] path = include/fc/crypto/webauthn_json url = https://github.com/Tencent/rapidjson/ +[submodule "secp256k1/secp256k1"] + path = secp256k1/secp256k1 + url = https://github.com/bitcoin-core/secp256k1 diff --git a/include/fc/crypto/elliptic.hpp b/include/fc/crypto/elliptic.hpp index 26128682b..c16e645a4 100644 --- a/include/fc/crypto/elliptic.hpp +++ b/include/fc/crypto/elliptic.hpp @@ -24,7 +24,6 @@ namespace fc { typedef fc::array public_key_point_data; ///< the full non-compressed version of the ECC point typedef fc::array signature; typedef fc::array compact_signature; - typedef std::vector range_proof_type; typedef fc::array extended_key_data; typedef fc::sha256 blinded_hash; typedef fc::sha256 blind_signature; @@ -53,11 +52,6 @@ namespace fc { public_key child( const fc::sha256& offset )const; bool valid()const; - /** Computes new pubkey = generator * offset + old pubkey ?! */ -// public_key mult( const fc::sha256& offset )const; - /** Computes new pubkey = regenerate(offset).pubkey + old pubkey - * = offset * G + 1 * old pubkey ?! */ - public_key add( const fc::sha256& offset )const; public_key( public_key&& pk ); public_key& operator=( public_key&& pk ); @@ -150,39 +144,6 @@ namespace fc { fc::fwd my; }; - struct range_proof_info - { - int exp; - int mantissa; - uint64_t min_value; - uint64_t max_value; - }; - - commitment_type blind( const blind_factor_type& blind, uint64_t value ); - blind_factor_type blind_sum( const std::vector& blinds, uint32_t non_neg ); - /** verifies taht commnits + neg_commits + excess == 0 */ - bool verify_sum( const std::vector& commits, const std::vector& neg_commits, int64_t excess ); - bool verify_range( uint64_t& min_val, uint64_t& max_val, const commitment_type& commit, const range_proof_type& proof ); - - range_proof_type range_proof_sign( uint64_t min_value, - const commitment_type& commit, - const blind_factor_type& commit_blind, - const blind_factor_type& nonce, - int8_t base10_exp, - uint8_t min_bits, - uint64_t actual_value - ); - - bool verify_range_proof_rewind( blind_factor_type& blind_out, - uint64_t& value_out, - string& message_out, - const blind_factor_type& nonce, - uint64_t& min_val, - uint64_t& max_val, - commitment_type commit, - const range_proof_type& proof ); - range_proof_info range_get_info( const range_proof_type& proof ); - /** * Shims */ @@ -273,7 +234,6 @@ namespace fc { FC_REFLECT_TYPENAME( fc::ecc::private_key ) FC_REFLECT_TYPENAME( fc::ecc::public_key ) -FC_REFLECT( fc::ecc::range_proof_info, (exp)(mantissa)(min_value)(max_value) ) FC_REFLECT_DERIVED( fc::ecc::public_key_shim, (fc::crypto::shim), BOOST_PP_SEQ_NIL ) FC_REFLECT_DERIVED( fc::ecc::signature_shim, (fc::crypto::shim), BOOST_PP_SEQ_NIL ) FC_REFLECT_DERIVED( fc::ecc::private_key_shim, (fc::crypto::shim), BOOST_PP_SEQ_NIL ) diff --git a/include/fc/crypto/elliptic_r1.hpp b/include/fc/crypto/elliptic_r1.hpp index 16dddde89..1ada2a9d6 100644 --- a/include/fc/crypto/elliptic_r1.hpp +++ b/include/fc/crypto/elliptic_r1.hpp @@ -37,7 +37,6 @@ namespace fc { ~public_key(); bool verify( const fc::sha256& digest, const signature& sig ); public_key_data serialize()const; - public_key_point_data serialize_ecc_point()const; operator public_key_data()const { return serialize(); } diff --git a/secp256k1/CMakeLists.txt b/secp256k1/CMakeLists.txt index 5d2ab0f9e..19056d415 100644 --- a/secp256k1/CMakeLists.txt +++ b/secp256k1/CMakeLists.txt @@ -21,16 +21,16 @@ else() endif() add_library(secp256k1 STATIC - upstream/src/secp256k1.c + secp256k1/src/secp256k1.c ) target_include_directories(secp256k1 PUBLIC - ${CMAKE_CURRENT_SOURCE_DIR}/upstream/ - ${CMAKE_CURRENT_SOURCE_DIR}/upstream/include + secp256k1 + secp256k1/include PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR}/upstream/src - ${SECP256K1_CONFIG_INC_DIR} + secp256k1/src + "${SECP256K1_CONFIG_INC_DIR}" ${GMP_INCLUDE_DIR} ) diff --git a/secp256k1/config_with_gmp/libsecp256k1-config.h b/secp256k1/config_with_gmp/libsecp256k1-config.h index c1f4762c9..000953f9b 100644 --- a/secp256k1/config_with_gmp/libsecp256k1-config.h +++ b/secp256k1/config_with_gmp/libsecp256k1-config.h @@ -1,9 +1,9 @@ #pragma once -//optimizations that any compiler we target have -#define HAVE_BUILTIN_CLZLL 1 -#define HAVE_BUILTIN_EXPECT 1 -#define HAVE___INT128 1 +#define ENABLE_MODULE_RECOVERY 1 + +#define ECMULT_GEN_PREC_BITS 4 +#define ECMULT_WINDOW_SIZE 15 //use GMP for bignum #define HAVE_LIBGMP 1 @@ -11,10 +11,6 @@ #define USE_FIELD_INV_NUM 1 #define USE_SCALAR_INV_NUM 1 -//use impls best for 64-bit -#define USE_FIELD_5X52 1 -#define USE_SCALAR_4X64 1 - //enable asm #ifdef __x86_64__ #define USE_ASM_X86_64 1 diff --git a/secp256k1/config_without_gmp/libsecp256k1-config.h b/secp256k1/config_without_gmp/libsecp256k1-config.h index 24ed1c987..a81452121 100644 --- a/secp256k1/config_without_gmp/libsecp256k1-config.h +++ b/secp256k1/config_without_gmp/libsecp256k1-config.h @@ -1,19 +1,15 @@ #pragma once -//optimizations that any compiler we target have -#define HAVE_BUILTIN_CLZLL 1 -#define HAVE_BUILTIN_EXPECT 1 -#define HAVE___INT128 1 +#define ENABLE_MODULE_RECOVERY 1 + +#define ECMULT_GEN_PREC_BITS 4 +#define ECMULT_WINDOW_SIZE 15 //use internal field & num impls #define USE_FIELD_INV_BUILTIN 1 #define USE_SCALAR_INV_BUILTIN 1 #define USE_NUM_NONE 1 -//use impls best for 64-bit -#define USE_FIELD_5X52 1 -#define USE_SCALAR_4X64 1 - //enable asm #ifdef __x86_64__ #define USE_ASM_X86_64 1 diff --git a/secp256k1/secp256k1 b/secp256k1/secp256k1 new file mode 160000 index 000000000..b61f9da54 --- /dev/null +++ b/secp256k1/secp256k1 @@ -0,0 +1 @@ +Subproject commit b61f9da54eff6d8137e0681b403b48be62f0460a diff --git a/secp256k1/upstream b/secp256k1/upstream deleted file mode 160000 index bd067945e..000000000 --- a/secp256k1/upstream +++ /dev/null @@ -1 +0,0 @@ -Subproject commit bd067945ead3b514fba884abd0de95fc4b5db9ae diff --git a/src/crypto/_elliptic_impl_priv.hpp b/src/crypto/_elliptic_impl_priv.hpp index 8c2a1abff..45d0ef879 100644 --- a/src/crypto/_elliptic_impl_priv.hpp +++ b/src/crypto/_elliptic_impl_priv.hpp @@ -8,7 +8,7 @@ namespace fc { namespace ecc { namespace detail { -const secp256k1_context_t* _get_context(); +const secp256k1_context* _get_context(); void _init_lib(); class private_key_impl diff --git a/src/crypto/elliptic_common.cpp b/src/crypto/elliptic_common.cpp index 33547f39e..4fa0925b9 100644 --- a/src/crypto/elliptic_common.cpp +++ b/src/crypto/elliptic_common.cpp @@ -110,15 +110,6 @@ namespace fc { namespace ecc { return public_key(data); } - public_key public_key::child( const fc::sha256& offset )const - { - fc::sha256::encoder enc; - fc::raw::pack( enc, *this ); - fc::raw::pack( enc, offset ); - - return add( enc.result() ); - } - private_key private_key::child( const fc::sha256& offset )const { fc::sha256::encoder enc; diff --git a/src/crypto/elliptic_impl_priv.cpp b/src/crypto/elliptic_impl_priv.cpp index 585ffdef1..1134c0b4b 100644 --- a/src/crypto/elliptic_impl_priv.cpp +++ b/src/crypto/elliptic_impl_priv.cpp @@ -1,6 +1,7 @@ #include #include +#include #include "_elliptic_impl_priv.hpp" @@ -71,30 +72,35 @@ namespace fc { namespace ecc { { FC_ASSERT( my->_key != empty_priv ); public_key_data pub; - unsigned int pk_len; - FC_ASSERT( secp256k1_ec_pubkey_create( detail::_get_context(), (unsigned char*) pub.begin(), (int*) &pk_len, (unsigned char*) my->_key.data(), 1 ) ); - FC_ASSERT( pk_len == pub.size() ); + size_t pub_len = sizeof(pub); + secp256k1_pubkey secp_pub; + FC_ASSERT( secp256k1_ec_pubkey_create( detail::_get_context(), &secp_pub, (unsigned char*) my->_key.data() ) ); + secp256k1_ec_pubkey_serialize( detail::_get_context(), (unsigned char*)&pub, &pub_len, &secp_pub, SECP256K1_EC_COMPRESSED ); + FC_ASSERT( pub_len == pub.size() ); return public_key(pub); } static int extended_nonce_function( unsigned char *nonce32, const unsigned char *msg32, - const unsigned char *key32, unsigned int attempt, - const void *data ) { + const unsigned char *key32, const unsigned char* algo16, + void* data, unsigned int attempt ) { unsigned int* extra = (unsigned int*) data; (*extra)++; - return secp256k1_nonce_function_default( nonce32, msg32, key32, *extra, nullptr ); + return secp256k1_nonce_function_default( nonce32, msg32, key32, algo16, nullptr, *extra ); } compact_signature private_key::sign_compact( const fc::sha256& digest, bool require_canonical )const { FC_ASSERT( my->_key != empty_priv ); compact_signature result; + secp256k1_ecdsa_recoverable_signature secp_sig; int recid; unsigned int counter = 0; do { - FC_ASSERT( secp256k1_ecdsa_sign_compact( detail::_get_context(), (unsigned char*) digest.data(), (unsigned char*) result.begin() + 1, (unsigned char*) my->_key.data(), extended_nonce_function, &counter, &recid )); + FC_ASSERT( secp256k1_ecdsa_sign_recoverable( detail::_get_context(), &secp_sig, (unsigned char*) digest.data(), (unsigned char*) my->_key.data(), extended_nonce_function, &counter )); + secp256k1_ecdsa_recoverable_signature_serialize_compact( detail::_get_context(), result.data + 1, &recid, &secp_sig); } while( require_canonical && !public_key::is_canonical( result ) ); + result.begin()[0] = 27 + 4 + recid; return result; } diff --git a/src/crypto/elliptic_r1.cpp b/src/crypto/elliptic_r1.cpp index da8044294..84b318f20 100644 --- a/src/crypto/elliptic_r1.cpp +++ b/src/crypto/elliptic_r1.cpp @@ -458,15 +458,6 @@ namespace fc { namespace crypto { namespace r1 { EC_POINT_get_affine_coordinates_GFp( group, pub, self.my->_pub_x.get(), self.my->_pub_y.get(), nullptr ); */ } - public_key_point_data public_key::serialize_ecc_point()const - { - public_key_point_data dat; - if( !my->_key ) return dat; - EC_KEY_set_conv_form( my->_key, POINT_CONVERSION_UNCOMPRESSED ); - char* front = &dat.data[0]; - i2o_ECPublicKey( my->_key, (unsigned char**)&front ); - return dat; - } public_key::public_key() { diff --git a/src/crypto/elliptic_secp256k1.cpp b/src/crypto/elliptic_secp256k1.cpp index 826d57358..84eacf44f 100644 --- a/src/crypto/elliptic_secp256k1.cpp +++ b/src/crypto/elliptic_secp256k1.cpp @@ -10,6 +10,7 @@ #include #include +#include #if _WIN32 # include @@ -24,13 +25,13 @@ namespace fc { namespace ecc { namespace detail { - const secp256k1_context_t* _get_context() { - static secp256k1_context_t* ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY | SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_RANGEPROOF | SECP256K1_CONTEXT_COMMIT ); + const secp256k1_context* _get_context() { + static secp256k1_context* ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY | SECP256K1_CONTEXT_SIGN); return ctx; } void _init_lib() { - static const secp256k1_context_t* ctx = _get_context(); + static const secp256k1_context* ctx = _get_context(); static int init_o = init_openssl(); (void)ctx; (void)init_o; @@ -70,9 +71,14 @@ namespace fc { namespace ecc { static const private_key_secret empty_priv; FC_ASSERT( my->_key != empty_priv ); FC_ASSERT( other.my->_key != empty_pub ); - public_key_data pub(other.my->_key); - FC_ASSERT( secp256k1_ec_pubkey_tweak_mul( detail::_get_context(), (unsigned char*) pub.begin(), pub.size(), (unsigned char*) my->_key.data() ) ); - return fc::sha512::hash( pub.begin() + 1, pub.size() - 1 ); + secp256k1_pubkey secp_pubkey; + FC_ASSERT( secp256k1_ec_pubkey_parse( detail::_get_context(), &secp_pubkey, (unsigned char*)other.serialize().data, other.serialize().size() ) ); + FC_ASSERT( secp256k1_ec_pubkey_tweak_mul( detail::_get_context(), &secp_pubkey, (unsigned char*) my->_key.data() ) ); + public_key_data serialized_result; + size_t serialized_result_sz = sizeof(serialized_result); + secp256k1_ec_pubkey_serialize(detail::_get_context(), (unsigned char*)&serialized_result.data, &serialized_result_sz, &secp_pubkey, SECP256K1_EC_COMPRESSED ); + FC_ASSERT( serialized_result_sz == sizeof(serialized_result) ); + return fc::sha512::hash( serialized_result.begin() + 1, serialized_result.size() - 1 ); } @@ -101,15 +107,6 @@ namespace fc { namespace ecc { return my->_key != empty_pub; } - public_key public_key::add( const fc::sha256& digest )const - { - FC_ASSERT( my->_key != empty_pub ); - public_key_data new_key; - memcpy( new_key.begin(), my->_key.begin(), new_key.size() ); - FC_ASSERT( secp256k1_ec_pubkey_tweak_add( detail::_get_context(), (unsigned char*) new_key.begin(), new_key.size(), (unsigned char*) digest.data() ) ); - return public_key( new_key ); - } - std::string public_key::to_base58() const { FC_ASSERT( my->_key != empty_pub ); @@ -122,17 +119,6 @@ namespace fc { namespace ecc { return my->_key; } - public_key_point_data public_key::serialize_ecc_point()const - { - FC_ASSERT( my->_key != empty_pub ); - public_key_point_data dat; - unsigned int pk_len = my->_key.size(); - memcpy( dat.begin(), my->_key.begin(), pk_len ); - FC_ASSERT( secp256k1_ec_pubkey_decompress( detail::_get_context(), (unsigned char *) dat.begin(), (int*) &pk_len ) ); - FC_ASSERT( pk_len == dat.size() ); - return dat; - } - public_key::public_key( const public_key_point_data& dat ) { const char* front = &dat.data[0]; @@ -165,108 +151,15 @@ namespace fc { namespace ecc { FC_ASSERT( is_canonical( c ), "signature is not canonical" ); } - unsigned int pk_len; - FC_ASSERT( secp256k1_ecdsa_recover_compact( detail::_get_context(), (unsigned char*) digest.data(), (unsigned char*) c.begin() + 1, (unsigned char*) my->_key.begin(), (int*) &pk_len, 1, (*c.begin() - 27) & 3 ) ); - FC_ASSERT( pk_len == my->_key.size() ); - } - - - commitment_type blind( const blind_factor_type& blind, uint64_t value ) - { - commitment_type result; - FC_ASSERT( secp256k1_pedersen_commit( detail::_get_context(), (unsigned char*)&result, (unsigned char*)&blind, value ) ); - return result; - } + secp256k1_pubkey secp_pub; + secp256k1_ecdsa_recoverable_signature secp_sig; - blind_factor_type blind_sum( const std::vector& blinds_in, uint32_t non_neg ) - { - blind_factor_type result; - std::vector blinds(blinds_in.size()); - for( uint32_t i = 0; i < blinds_in.size(); ++i ) blinds[i] = (const unsigned char*)&blinds_in[i]; - FC_ASSERT( secp256k1_pedersen_blind_sum( detail::_get_context(), (unsigned char*)&result, blinds.data(), blinds_in.size(), non_neg ) ); - return result; - } - - /** verifies taht commnits + neg_commits + excess == 0 */ - bool verify_sum( const std::vector& commits_in, const std::vector& neg_commits_in, int64_t excess ) - { - std::vector commits(commits_in.size()); - for( uint32_t i = 0; i < commits_in.size(); ++i ) commits[i] = (const unsigned char*)&commits_in[i]; - std::vector neg_commits(neg_commits_in.size()); - for( uint32_t i = 0; i < neg_commits_in.size(); ++i ) neg_commits[i] = (const unsigned char*)&neg_commits_in[i]; - - return secp256k1_pedersen_verify_tally( detail::_get_context(), commits.data(), commits.size(), neg_commits.data(), neg_commits.size(), excess ); - } - - bool verify_range( uint64_t& min_val, uint64_t& max_val, const commitment_type& commit, const std::vector& proof ) - { - return secp256k1_rangeproof_verify( detail::_get_context(), &min_val, &max_val, (const unsigned char*)&commit, (const unsigned char*)proof.data(), proof.size() ); - } - - std::vector range_proof_sign( uint64_t min_value, - const commitment_type& commit, - const blind_factor_type& commit_blind, - const blind_factor_type& nonce, - int8_t base10_exp, - uint8_t min_bits, - uint64_t actual_value - ) - { - int proof_len = 5134; - std::vector proof(proof_len); - - FC_ASSERT( secp256k1_rangeproof_sign( detail::_get_context(), - (unsigned char*)proof.data(), - &proof_len, min_value, - (const unsigned char*)&commit, - (const unsigned char*)&commit_blind, - (const unsigned char*)&nonce, - base10_exp, min_bits, actual_value ) ); - proof.resize(proof_len); - return proof; - } - - - bool verify_range_proof_rewind( blind_factor_type& blind_out, - uint64_t& value_out, - string& message_out, - const blind_factor_type& nonce, - uint64_t& min_val, - uint64_t& max_val, - commitment_type commit, - const std::vector& proof ) - { - char msg[4096]; - int mlen = 0; - FC_ASSERT( secp256k1_rangeproof_rewind( detail::_get_context(), - (unsigned char*)&blind_out, - &value_out, - (unsigned char*)msg, - &mlen, - (const unsigned char*)&nonce, - &min_val, - &max_val, - (const unsigned char*)&commit, - (const unsigned char*)proof.data(), - proof.size() ) ); - - message_out = std::string( msg, mlen ); - return true; - } - - range_proof_info range_get_info( const std::vector& proof ) - { - range_proof_info result; - FC_ASSERT( secp256k1_rangeproof_info( detail::_get_context(), - (int*)&result.exp, - (int*)&result.mantissa, - (uint64_t*)&result.min_value, - (uint64_t*)&result.max_value, - (const unsigned char*)proof.data(), - (int)proof.size() ) ); - - return result; - } + FC_ASSERT( secp256k1_ecdsa_recoverable_signature_parse_compact( detail::_get_context(), &secp_sig, (unsigned char*)c.begin() + 1, (*c.begin() - 27) & 3) ); + FC_ASSERT( secp256k1_ecdsa_recover( detail::_get_context(), &secp_pub, &secp_sig, (unsigned char*) digest.data() ) ); + size_t serialized_result_sz = my->_key.size(); + secp256k1_ec_pubkey_serialize( detail::_get_context(), (unsigned char*)&my->_key.data, &serialized_result_sz, &secp_pub, SECP256K1_EC_COMPRESSED ); + FC_ASSERT( serialized_result_sz == my->_key.size() ); + } } } From 16f41313403ce5f204b70c24ce8d4848599ada8f Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Wed, 20 Jan 2021 21:18:45 -0600 Subject: [PATCH 069/124] Consistent declaration --- include/fc/fwd.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/fc/fwd.hpp b/include/fc/fwd.hpp index d2f794534..33488d28a 100644 --- a/include/fc/fwd.hpp +++ b/include/fc/fwd.hpp @@ -12,8 +12,8 @@ class fwd { public: template fwd( U&& u ); template fwd( U&& u, V&& v ); - template fwd( U&& u, V&& v, X&& ); - template fwd( U&& u, V&& v, X&&, Y&& ); + template fwd( U&& u, V&& v, X&& x); + template fwd( U&& u, V&& v, X&& x, Y&& y); fwd(); fwd( const fwd& f ); From 456ee3554e5cd7cabffd721f991f8f2026b925b1 Mon Sep 17 00:00:00 2001 From: Matt Witherspoon <32485495+spoonincode@users.noreply.github.com> Date: Mon, 1 Feb 2021 11:38:48 -0500 Subject: [PATCH 070/124] add impl for blob to/from_variant --- src/variant.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/variant.cpp b/src/variant.cpp index bea6f5c61..d91a913bc 100644 --- a/src/variant.cpp +++ b/src/variant.cpp @@ -714,6 +714,15 @@ void from_variant( const variant& var, std::vector& vo ) } } +void to_variant( const blob& b, variant& v ) { + v = variant(base64_encode(b.data.data(), b.data.size())); +} + +void from_variant( const variant& v, blob& b ) { + string _s = base64_decode(v.as_string()); + b.data = std::vector(_s.begin(), _s.end()); +} + void to_variant( const UInt<8>& n, variant& v ) { v = uint64_t(n); } // TODO: warn on overflow? void from_variant( const variant& v, UInt<8>& n ) { n = static_cast(v.as_uint64()); } From c83f6295ea4b40c750a17cf8f9978e131f3bf92c Mon Sep 17 00:00:00 2001 From: James Folk Date: Tue, 2 Feb 2021 15:54:01 -0500 Subject: [PATCH 071/124] added defensive programming practices to cfile to ensure that a user cannot use it if it is closed --- include/fc/io/cfile.hpp | 121 ++++++++++++++++++++++++++++------------ test/io/test_cfile.cpp | 41 ++++++++++++++ 2 files changed, 126 insertions(+), 36 deletions(-) diff --git a/include/fc/io/cfile.hpp b/include/fc/io/cfile.hpp index ec62e0ca4..29417b194 100644 --- a/include/fc/io/cfile.hpp +++ b/include/fc/io/cfile.hpp @@ -27,14 +27,16 @@ class cfile_datastream; class cfile { public: cfile() - : _file(nullptr, &fclose) + : _open(false), + _file_path(""), + _file(nullptr, &fclose) {} - void set_file_path( fc::path file_path ) { + void set_file_path( const fc::path &file_path ) { _file_path = std::move( file_path ); } - fc::path get_file_path() const { + const fc::path &get_file_path() const { return _file_path; } @@ -49,6 +51,9 @@ class cfile { /// "ab+" - open for binary update - create if does not exist /// "rb+" - open for binary update - file must exist void open( const char* mode ) { + if(_open) + fclose(_file.get()); + _file.reset( FC_FOPEN( _file_path.generic_string().c_str(), mode ) ); if( !_file ) { throw std::ios_base::failure( "cfile unable to open: " + _file_path.generic_string() + " in mode: " + std::string( mode ) ); @@ -57,6 +62,9 @@ class cfile { } size_t tellp() const { + if(!_open) + throw std::ios_base::failure("cfile is not open"); + long result = ftell( _file.get() ); if (result == -1) throw std::ios_base::failure("cfile: " + get_file_path().generic_string() + @@ -65,77 +73,118 @@ class cfile { } void seek( long loc ) { - if( 0 != fseek( _file.get(), loc, SEEK_SET ) ) { + if(!_open) + throw std::ios_base::failure("cfile is not open"); + + if( 0 != fseek( _file.get(), loc, SEEK_SET ) ) { throw std::ios_base::failure( "cfile: " + _file_path.generic_string() + " unable to SEEK_SET to: " + std::to_string(loc) ); - } + } } void seek_end( long loc ) { - if( 0 != fseek( _file.get(), loc, SEEK_END ) ) { + if(!_open) + throw std::ios_base::failure("cfile is not open"); + + if( 0 != fseek( _file.get(), loc, SEEK_END ) ) { throw std::ios_base::failure( "cfile: " + _file_path.generic_string() + " unable to SEEK_END to: " + std::to_string(loc) ); - } + } } void skip( long loc) { - if( 0 != fseek( _file.get(), loc, SEEK_CUR ) ) { + if(!_open) + throw std::ios_base::failure("cfile is not open"); + + if( 0 != fseek( _file.get(), loc, SEEK_CUR ) ) { throw std::ios_base::failure( "cfile: " + _file_path.generic_string() + " unable to SEEK_CUR to: " + std::to_string(loc) ); } } void read( char* d, size_t n ) { - size_t result = fread( d, 1, n, _file.get() ); - if( result != n ) { - throw std::ios_base::failure( "cfile: " + _file_path.generic_string() + + if(!_open) + throw std::ios_base::failure("cfile is not open"); + + size_t result = fread( d, 1, n, _file.get() ); + + if( result != n ) { + throw std::ios_base::failure( "cfile: " + _file_path.generic_string() + " unable to read " + std::to_string( n ) + " bytes; only read " + std::to_string( result ) ); - } + } } void write( const char* d, size_t n ) { - size_t result = fwrite( d, 1, n, _file.get() ); - if( result != n ) { - throw std::ios_base::failure( "cfile: " + _file_path.generic_string() + + if(!_open) + throw std::ios_base::failure("cfile is not open"); + + size_t result = fwrite( d, 1, n, _file.get() ); + + if( result != n ) { + throw std::ios_base::failure( "cfile: " + _file_path.generic_string() + " unable to write " + std::to_string( n ) + " bytes; only wrote " + std::to_string( result ) ); - } + } } void flush() { - if( 0 != fflush( _file.get() ) ) { - int ec = ferror( _file.get() ); - throw std::ios_base::failure( "cfile: " + _file_path.generic_string() + + if(!_open) + throw std::ios_base::failure("cfile is not open"); + + if( 0 != fflush( _file.get() ) ) { + int ec = ferror( _file.get() ); + throw std::ios_base::failure( "cfile: " + _file_path.generic_string() + " unable to flush file, ferror: " + std::to_string( ec ) ); - } + } } void sync() { - const int fd = fileno(_file.get() ); - if( -1 == fd ) { - throw std::ios_base::failure( "cfile: " + _file_path.generic_string() + + if(!_open) + throw std::ios_base::failure("cfile is not open"); + + const int fd = fileno(_file.get() ); + + if( -1 == fd ) { + throw std::ios_base::failure( "cfile: " + _file_path.generic_string() + " unable to convert file pointer to file descriptor, error: " + std::to_string( errno ) ); - } - if( -1 == fsync( fd ) ) { - throw std::ios_base::failure( "cfile: " + _file_path.generic_string() + + } + + if( -1 == fsync( fd ) ) { + throw std::ios_base::failure( "cfile: " + _file_path.generic_string() + " unable to sync file, error: " + std::to_string( errno ) ); - } + } } - bool eof() const { return feof(_file.get()) != 0; } + bool eof() const { + if(!_open) + throw std::ios_base::failure("cfile is not open"); - int getc() { - int ret = fgetc(_file.get()); - if (ret == EOF) { - throw std::ios_base::failure( "cfile: " + _file_path.generic_string() + + if(feof(_file.get()))return true; + + int c = fgetc(_file.get()); + if(EOF == c)return true; + + return (EOF == ungetc(c, _file.get())); + } + + int getc() { + if(!_open) + throw std::ios_base::failure("cfile is not open"); + + int ret = fgetc(_file.get()); + + if (ret == EOF) { + throw std::ios_base::failure( "cfile: " + _file_path.generic_string() + " unable to read 1 byte"); - } - return ret; + } + return ret; } void close() { - _file.reset(); - _open = false; + if(_open) { + _file.reset(); + _open = false; + } } cfile_datastream create_datastream(); diff --git a/test/io/test_cfile.cpp b/test/io/test_cfile.cpp index f8c51360f..fcae22b29 100644 --- a/test/io/test_cfile.cpp +++ b/test/io/test_cfile.cpp @@ -1,5 +1,6 @@ #define BOOST_TEST_MODULE io #include +#include #include @@ -58,4 +59,44 @@ BOOST_AUTO_TEST_SUITE(cfile_test_suite) BOOST_CHECK( !fc::exists( tempdir.path() / "test") ); } + BOOST_AUTO_TEST_CASE(test_eof) + { + fc::temp_file tmpfile; + { + boost::filesystem::ofstream ofs(tmpfile.path()); + ofs << "the quick brown fox"; + } + + cfile t; + t.set_file_path(tmpfile.path()); + BOOST_CHECK_NO_THROW(t.open("r")); + BOOST_CHECK(t.is_open()); + BOOST_CHECK_NO_THROW(!t.eof()); + BOOST_CHECK_NO_THROW(t.getc() == 't'); + BOOST_CHECK_NO_THROW(t.skip(10)); + BOOST_CHECK_NO_THROW(!t.eof()); + BOOST_CHECK_NO_THROW(t.getc() == 'r'); + BOOST_CHECK_NO_THROW(t.skip(7)); + BOOST_CHECK_NO_THROW(t.eof()); + BOOST_CHECK_THROW(t.getc(), std::ios_base::failure); + + BOOST_CHECK_NO_THROW(t.open("r")); + BOOST_CHECK_NO_THROW(!t.eof()); + BOOST_CHECK_NO_THROW(t.skip(30)); + BOOST_CHECK_NO_THROW(t.eof()); + + BOOST_CHECK_NO_THROW(t.open("r")); + BOOST_CHECK_NO_THROW(!t.eof()); + BOOST_CHECK_THROW(t.skip(-2), std::ios_base::failure); + + BOOST_CHECK_NO_THROW(t.open("r")); + BOOST_CHECK_NO_THROW(!t.eof()); + BOOST_CHECK_NO_THROW(t.skip(4)); + BOOST_CHECK_NO_THROW(!t.eof()); + BOOST_CHECK_NO_THROW(t.getc() == 'q'); + BOOST_CHECK_NO_THROW(t.skip(19)); + BOOST_CHECK_NO_THROW(t.eof()); + BOOST_CHECK_THROW(t.seek(25), std::ios_base::failure); + } + BOOST_AUTO_TEST_SUITE_END() From 0677c87ba6dd881288f3147ba03beb5311017fac Mon Sep 17 00:00:00 2001 From: James Folk Date: Tue, 2 Feb 2021 16:20:50 -0500 Subject: [PATCH 072/124] removed the const reference call --- include/fc/io/cfile.hpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/include/fc/io/cfile.hpp b/include/fc/io/cfile.hpp index 29417b194..a496b60a9 100644 --- a/include/fc/io/cfile.hpp +++ b/include/fc/io/cfile.hpp @@ -32,7 +32,12 @@ class cfile { _file(nullptr, &fclose) {} - void set_file_path( const fc::path &file_path ) { + ~cfile() { + if(_open) + fclose(_file.get()); + } + + void set_file_path( fc::path file_path ) { _file_path = std::move( file_path ); } From d3f86cddb70901f0e494df19253a7bb2137b7ddf Mon Sep 17 00:00:00 2001 From: James Folk Date: Tue, 2 Feb 2021 16:37:26 -0500 Subject: [PATCH 073/124] for the open function, after it was closing it before an attempt to open it again, I set the internal boolean flag to not open, just in case it might be thrown during the next open attempt --- include/fc/io/cfile.hpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/fc/io/cfile.hpp b/include/fc/io/cfile.hpp index a496b60a9..a8bfaa638 100644 --- a/include/fc/io/cfile.hpp +++ b/include/fc/io/cfile.hpp @@ -56,8 +56,10 @@ class cfile { /// "ab+" - open for binary update - create if does not exist /// "rb+" - open for binary update - file must exist void open( const char* mode ) { - if(_open) + if(_open) { fclose(_file.get()); + _open = false; + } _file.reset( FC_FOPEN( _file_path.generic_string().c_str(), mode ) ); if( !_file ) { From 5ced2265d64c02b36d127f04dd83cae6fcedcb18 Mon Sep 17 00:00:00 2001 From: James Folk Date: Tue, 2 Feb 2021 17:31:05 -0500 Subject: [PATCH 074/124] forgot that uptr cleans up the code. removed the extra eof checks --- include/fc/io/cfile.hpp | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/include/fc/io/cfile.hpp b/include/fc/io/cfile.hpp index a8bfaa638..344fb1b72 100644 --- a/include/fc/io/cfile.hpp +++ b/include/fc/io/cfile.hpp @@ -32,11 +32,6 @@ class cfile { _file(nullptr, &fclose) {} - ~cfile() { - if(_open) - fclose(_file.get()); - } - void set_file_path( fc::path file_path ) { _file_path = std::move( file_path ); } @@ -167,11 +162,6 @@ class cfile { throw std::ios_base::failure("cfile is not open"); if(feof(_file.get()))return true; - - int c = fgetc(_file.get()); - if(EOF == c)return true; - - return (EOF == ungetc(c, _file.get())); } int getc() { From ce737286e18a4f3c2af02916c1ebc3ff6894d179 Mon Sep 17 00:00:00 2001 From: James Folk Date: Wed, 3 Feb 2021 09:52:18 -0500 Subject: [PATCH 075/124] addressed code formatting issues --- include/fc/io/cfile.hpp | 144 ++++++++++++++++++++-------------------- 1 file changed, 71 insertions(+), 73 deletions(-) diff --git a/include/fc/io/cfile.hpp b/include/fc/io/cfile.hpp index 344fb1b72..a3e52dc2c 100644 --- a/include/fc/io/cfile.hpp +++ b/include/fc/io/cfile.hpp @@ -26,17 +26,17 @@ class cfile_datastream; */ class cfile { public: - cfile() - : _open(false), - _file_path(""), - _file(nullptr, &fclose) + cfile(): + _open(false), + _file_path(""), + _file(nullptr, &fclose) {} void set_file_path( fc::path file_path ) { _file_path = std::move( file_path ); } - const fc::path &get_file_path() const { + const fc::path& get_file_path() const { return _file_path; } @@ -51,10 +51,10 @@ class cfile { /// "ab+" - open for binary update - create if does not exist /// "rb+" - open for binary update - file must exist void open( const char* mode ) { - if(_open) { - fclose(_file.get()); - _open = false; - } + if(is_open()) { + fclose(_file.get()); + _open = false; + } _file.reset( FC_FOPEN( _file_path.generic_string().c_str(), mode ) ); if( !_file ) { @@ -64,8 +64,8 @@ class cfile { } size_t tellp() const { - if(!_open) - throw std::ios_base::failure("cfile is not open"); + if(!is_open()) + throw std::ios_base::failure("cfile is not open"); long result = ftell( _file.get() ); if (result == -1) @@ -75,119 +75,117 @@ class cfile { } void seek( long loc ) { - if(!_open) - throw std::ios_base::failure("cfile is not open"); - - if( 0 != fseek( _file.get(), loc, SEEK_SET ) ) { + if( 0 != fseek( _file.get(), loc, SEEK_SET ) ) { throw std::ios_base::failure( "cfile: " + _file_path.generic_string() + - " unable to SEEK_SET to: " + std::to_string(loc) ); - } + " unable to SEEK_SET to: " + std::to_string(loc) ); + } } void seek_end( long loc ) { - if(!_open) - throw std::ios_base::failure("cfile is not open"); + if(!is_open()) + throw std::ios_base::failure("cfile is not open"); - if( 0 != fseek( _file.get(), loc, SEEK_END ) ) { + if( 0 != fseek( _file.get(), loc, SEEK_END ) ) { throw std::ios_base::failure( "cfile: " + _file_path.generic_string() + " unable to SEEK_END to: " + std::to_string(loc) ); - } + } } void skip( long loc) { - if(!_open) - throw std::ios_base::failure("cfile is not open"); + if(!is_open()) + throw std::ios_base::failure("cfile is not open"); - if( 0 != fseek( _file.get(), loc, SEEK_CUR ) ) { + if( 0 != fseek( _file.get(), loc, SEEK_CUR ) ) { throw std::ios_base::failure( "cfile: " + _file_path.generic_string() + " unable to SEEK_CUR to: " + std::to_string(loc) ); } } void read( char* d, size_t n ) { - if(!_open) - throw std::ios_base::failure("cfile is not open"); + if(!is_open()) + throw std::ios_base::failure("cfile is not open"); - size_t result = fread( d, 1, n, _file.get() ); + size_t result = fread( d, 1, n, _file.get() ); - if( result != n ) { - throw std::ios_base::failure( "cfile: " + _file_path.generic_string() + - " unable to read " + std::to_string( n ) + " bytes; only read " + std::to_string( result ) ); - } + if( result != n ) { + throw std::ios_base::failure( "cfile: " + _file_path.generic_string() + + " unable to read " + std::to_string( n ) + " bytes; only read " + std::to_string( result ) ); + } } void write( const char* d, size_t n ) { - if(!_open) - throw std::ios_base::failure("cfile is not open"); + if(!is_open()) + throw std::ios_base::failure("cfile is not open"); - size_t result = fwrite( d, 1, n, _file.get() ); + size_t result = fwrite( d, 1, n, _file.get() ); - if( result != n ) { - throw std::ios_base::failure( "cfile: " + _file_path.generic_string() + - " unable to write " + std::to_string( n ) + " bytes; only wrote " + std::to_string( result ) ); - } + if( result != n ) { + throw std::ios_base::failure( "cfile: " + _file_path.generic_string() + + " unable to write " + std::to_string( n ) + " bytes; only wrote " + std::to_string( result ) ); + } } void flush() { - if(!_open) - throw std::ios_base::failure("cfile is not open"); + if(!is_open()) + throw std::ios_base::failure("cfile is not open"); - if( 0 != fflush( _file.get() ) ) { - int ec = ferror( _file.get() ); - throw std::ios_base::failure( "cfile: " + _file_path.generic_string() + - " unable to flush file, ferror: " + std::to_string( ec ) ); - } + if( 0 != fflush( _file.get() ) ) { + int ec = ferror( _file.get() ); + throw std::ios_base::failure( "cfile: " + _file_path.generic_string() + + " unable to flush file, ferror: " + std::to_string( ec ) ); + } } void sync() { - if(!_open) - throw std::ios_base::failure("cfile is not open"); + if(!is_open()) + throw std::ios_base::failure("cfile is not open"); - const int fd = fileno(_file.get() ); + const int fd = fileno(_file.get() ); - if( -1 == fd ) { - throw std::ios_base::failure( "cfile: " + _file_path.generic_string() + - " unable to convert file pointer to file descriptor, error: " + - std::to_string( errno ) ); - } + if( -1 == fd ) { + throw std::ios_base::failure( "cfile: " + _file_path.generic_string() + + " unable to convert file pointer to file descriptor, error: " + + std::to_string( errno ) ); + } - if( -1 == fsync( fd ) ) { - throw std::ios_base::failure( "cfile: " + _file_path.generic_string() + - " unable to sync file, error: " + std::to_string( errno ) ); - } + if( -1 == fsync( fd ) ) { + throw std::ios_base::failure( "cfile: " + _file_path.generic_string() + + " unable to sync file, error: " + std::to_string( errno ) ); + } } bool eof() const { - if(!_open) - throw std::ios_base::failure("cfile is not open"); + if(!is_open()) + throw std::ios_base::failure("cfile is not open"); - if(feof(_file.get()))return true; + if(feof(_file.get())) + return true; } int getc() { - if(!_open) - throw std::ios_base::failure("cfile is not open"); + if(!is_open()) + throw std::ios_base::failure("cfile is not open"); - int ret = fgetc(_file.get()); + int ret = fgetc(_file.get()); - if (ret == EOF) { - throw std::ios_base::failure( "cfile: " + _file_path.generic_string() + - " unable to read 1 byte"); - } - return ret; + if (ret == EOF) { + throw std::ios_base::failure( "cfile: " + _file_path.generic_string() + + " unable to read 1 byte"); + } + return ret; } void close() { - if(_open) { - _file.reset(); - _open = false; - } + if(is_open()) { + _file.reset(); + _open = false; + } } cfile_datastream create_datastream(); private: - bool _open = false; + bool _open; fc::path _file_path; detail::unique_file _file; }; From cd8892d8be98daba328a53c5c28633ce837c2968 Mon Sep 17 00:00:00 2001 From: James Folk Date: Wed, 3 Feb 2021 11:57:01 -0500 Subject: [PATCH 076/124] removed the fclose from the unique_ptr cleanup --- include/fc/io/cfile.hpp | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/include/fc/io/cfile.hpp b/include/fc/io/cfile.hpp index a3e52dc2c..557c4ad3e 100644 --- a/include/fc/io/cfile.hpp +++ b/include/fc/io/cfile.hpp @@ -15,7 +15,7 @@ namespace fc { namespace detail { - using unique_file = std::unique_ptr; + using unique_file = std::unique_ptr; } class cfile_datastream; @@ -25,15 +25,24 @@ class cfile_datastream; * std::ios_base::failure exception thrown for errors. */ class cfile { +private: + cfile(const cfile &) = delete; + cfile(const cfile &&) = delete; + const cfile& operator=(const cfile &) = delete; + const cfile&& operator=(const cfile &&) = delete; public: cfile(): _open(false), _file_path(""), - _file(nullptr, &fclose) + _file(nullptr) {} - void set_file_path( fc::path file_path ) { - _file_path = std::move( file_path ); + ~cfile() { + close(); + } + + void set_file_path( const fc::path& file_path ) { + _file_path = file_path; } const fc::path& get_file_path() const { @@ -51,10 +60,7 @@ class cfile { /// "ab+" - open for binary update - create if does not exist /// "rb+" - open for binary update - file must exist void open( const char* mode ) { - if(is_open()) { - fclose(_file.get()); - _open = false; - } + close(); _file.reset( FC_FOPEN( _file_path.generic_string().c_str(), mode ) ); if( !_file ) { @@ -177,7 +183,7 @@ class cfile { void close() { if(is_open()) { - _file.reset(); + fclose(_file.get()); _open = false; } } From c8b78ab87a2654f27e8c35d0fcc69960de627287 Mon Sep 17 00:00:00 2001 From: James Folk Date: Wed, 3 Feb 2021 14:27:59 -0500 Subject: [PATCH 077/124] removed the unique_ptr implementation for the FILE* --- include/fc/io/cfile.hpp | 36 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/include/fc/io/cfile.hpp b/include/fc/io/cfile.hpp index 557c4ad3e..ea0b3567e 100644 --- a/include/fc/io/cfile.hpp +++ b/include/fc/io/cfile.hpp @@ -14,10 +14,6 @@ namespace fc { -namespace detail { - using unique_file = std::unique_ptr; -} - class cfile_datastream; /** @@ -34,7 +30,7 @@ class cfile { cfile(): _open(false), _file_path(""), - _file(nullptr) + _file_ptr(nullptr) {} ~cfile() { @@ -62,8 +58,8 @@ class cfile { void open( const char* mode ) { close(); - _file.reset( FC_FOPEN( _file_path.generic_string().c_str(), mode ) ); - if( !_file ) { + _file_ptr = FC_FOPEN( _file_path.generic_string().c_str(), mode ); + if( !_file_ptr ) { throw std::ios_base::failure( "cfile unable to open: " + _file_path.generic_string() + " in mode: " + std::string( mode ) ); } _open = true; @@ -73,7 +69,7 @@ class cfile { if(!is_open()) throw std::ios_base::failure("cfile is not open"); - long result = ftell( _file.get() ); + long result = ftell( _file_ptr ); if (result == -1) throw std::ios_base::failure("cfile: " + get_file_path().generic_string() + " unable to get the current position of the file, error: " + std::to_string( errno )); @@ -81,7 +77,7 @@ class cfile { } void seek( long loc ) { - if( 0 != fseek( _file.get(), loc, SEEK_SET ) ) { + if( 0 != fseek( _file_ptr, loc, SEEK_SET ) ) { throw std::ios_base::failure( "cfile: " + _file_path.generic_string() + " unable to SEEK_SET to: " + std::to_string(loc) ); } @@ -91,7 +87,7 @@ class cfile { if(!is_open()) throw std::ios_base::failure("cfile is not open"); - if( 0 != fseek( _file.get(), loc, SEEK_END ) ) { + if( 0 != fseek( _file_ptr, loc, SEEK_END ) ) { throw std::ios_base::failure( "cfile: " + _file_path.generic_string() + " unable to SEEK_END to: " + std::to_string(loc) ); } @@ -101,7 +97,7 @@ class cfile { if(!is_open()) throw std::ios_base::failure("cfile is not open"); - if( 0 != fseek( _file.get(), loc, SEEK_CUR ) ) { + if( 0 != fseek( _file_ptr, loc, SEEK_CUR ) ) { throw std::ios_base::failure( "cfile: " + _file_path.generic_string() + " unable to SEEK_CUR to: " + std::to_string(loc) ); } @@ -111,7 +107,7 @@ class cfile { if(!is_open()) throw std::ios_base::failure("cfile is not open"); - size_t result = fread( d, 1, n, _file.get() ); + size_t result = fread( d, 1, n, _file_ptr ); if( result != n ) { throw std::ios_base::failure( "cfile: " + _file_path.generic_string() + @@ -123,7 +119,7 @@ class cfile { if(!is_open()) throw std::ios_base::failure("cfile is not open"); - size_t result = fwrite( d, 1, n, _file.get() ); + size_t result = fwrite( d, 1, n, _file_ptr ); if( result != n ) { throw std::ios_base::failure( "cfile: " + _file_path.generic_string() + @@ -135,8 +131,8 @@ class cfile { if(!is_open()) throw std::ios_base::failure("cfile is not open"); - if( 0 != fflush( _file.get() ) ) { - int ec = ferror( _file.get() ); + if( 0 != fflush( _file_ptr ) ) { + int ec = ferror( _file_ptr ); throw std::ios_base::failure( "cfile: " + _file_path.generic_string() + " unable to flush file, ferror: " + std::to_string( ec ) ); } @@ -146,7 +142,7 @@ class cfile { if(!is_open()) throw std::ios_base::failure("cfile is not open"); - const int fd = fileno(_file.get() ); + const int fd = fileno(_file_ptr ); if( -1 == fd ) { throw std::ios_base::failure( "cfile: " + _file_path.generic_string() + @@ -164,7 +160,7 @@ class cfile { if(!is_open()) throw std::ios_base::failure("cfile is not open"); - if(feof(_file.get())) + if(feof(_file_ptr)) return true; } @@ -172,7 +168,7 @@ class cfile { if(!is_open()) throw std::ios_base::failure("cfile is not open"); - int ret = fgetc(_file.get()); + int ret = fgetc(_file_ptr); if (ret == EOF) { throw std::ios_base::failure( "cfile: " + _file_path.generic_string() + @@ -183,7 +179,7 @@ class cfile { void close() { if(is_open()) { - fclose(_file.get()); + fclose(_file_ptr); _open = false; } } @@ -193,7 +189,7 @@ class cfile { private: bool _open; fc::path _file_path; - detail::unique_file _file; + FILE *_file_ptr; }; /* From 7cc6bee4c20efac135a689e42f1b6bc3022e0c04 Mon Sep 17 00:00:00 2001 From: James Folk Date: Thu, 4 Feb 2021 10:09:57 -0500 Subject: [PATCH 078/124] updated the remaining functipn --- include/fc/io/cfile.hpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/include/fc/io/cfile.hpp b/include/fc/io/cfile.hpp index ea0b3567e..c656fc021 100644 --- a/include/fc/io/cfile.hpp +++ b/include/fc/io/cfile.hpp @@ -227,6 +227,8 @@ inline cfile_datastream cfile::create_datastream() { template <> class datastream : public fc::cfile { +private: + char mCurrentChar = 'EOF'; public: using fc::cfile::cfile; @@ -234,10 +236,13 @@ class datastream : public fc::cfile { bool get(char& c) { c = this->getc(); + mCurrentChar = c; return true; } - bool remaining() { return !this->eof(); } + bool remaining() const { + return (mCurrentChar != EOF); + } fc::cfile& storage() { return *this; } const fc::cfile& storage() const { return *this; } From 3c834859f8b01105381e9116c263b7fba8fe3e64 Mon Sep 17 00:00:00 2001 From: James Folk Date: Thu, 4 Feb 2021 10:30:55 -0500 Subject: [PATCH 079/124] Fixed the ``remaining`` function so that it now just checks if the current getc is EOF. Added deleted constructors for cfile, cfile_datastream and, datastream. --- include/fc/io/cfile.hpp | 112 +++++++++++++++++++--------------------- test/io/test_cfile.cpp | 78 ++++++++++++++-------------- 2 files changed, 93 insertions(+), 97 deletions(-) diff --git a/include/fc/io/cfile.hpp b/include/fc/io/cfile.hpp index c656fc021..7c2b23e8e 100644 --- a/include/fc/io/cfile.hpp +++ b/include/fc/io/cfile.hpp @@ -14,6 +14,10 @@ namespace fc { +namespace detail { + using unique_file = std::unique_ptr; +} + class cfile_datastream; /** @@ -21,22 +25,11 @@ class cfile_datastream; * std::ios_base::failure exception thrown for errors. */ class cfile { -private: - cfile(const cfile &) = delete; - cfile(const cfile &&) = delete; - const cfile& operator=(const cfile &) = delete; - const cfile&& operator=(const cfile &&) = delete; public: - cfile(): - _open(false), - _file_path(""), - _file_ptr(nullptr) + cfile() + : _file(nullptr, &fclose) {} - ~cfile() { - close(); - } - void set_file_path( const fc::path& file_path ) { _file_path = file_path; } @@ -56,10 +49,8 @@ class cfile { /// "ab+" - open for binary update - create if does not exist /// "rb+" - open for binary update - file must exist void open( const char* mode ) { - close(); - - _file_ptr = FC_FOPEN( _file_path.generic_string().c_str(), mode ); - if( !_file_ptr ) { + _file.reset( FC_FOPEN( _file_path.generic_string().c_str(), mode ) ); + if( !_file ) { throw std::ios_base::failure( "cfile unable to open: " + _file_path.generic_string() + " in mode: " + std::string( mode ) ); } _open = true; @@ -69,7 +60,7 @@ class cfile { if(!is_open()) throw std::ios_base::failure("cfile is not open"); - long result = ftell( _file_ptr ); + long result = ftell( _file.get() ); if (result == -1) throw std::ios_base::failure("cfile: " + get_file_path().generic_string() + " unable to get the current position of the file, error: " + std::to_string( errno )); @@ -77,9 +68,9 @@ class cfile { } void seek( long loc ) { - if( 0 != fseek( _file_ptr, loc, SEEK_SET ) ) { + if( 0 != fseek( _file.get(), loc, SEEK_SET ) ) { throw std::ios_base::failure( "cfile: " + _file_path.generic_string() + - " unable to SEEK_SET to: " + std::to_string(loc) ); + " unable to SEEK_SET to: " + std::to_string(loc) ); } } @@ -87,7 +78,7 @@ class cfile { if(!is_open()) throw std::ios_base::failure("cfile is not open"); - if( 0 != fseek( _file_ptr, loc, SEEK_END ) ) { + if( 0 != fseek( _file.get(), loc, SEEK_END ) ) { throw std::ios_base::failure( "cfile: " + _file_path.generic_string() + " unable to SEEK_END to: " + std::to_string(loc) ); } @@ -97,7 +88,7 @@ class cfile { if(!is_open()) throw std::ios_base::failure("cfile is not open"); - if( 0 != fseek( _file_ptr, loc, SEEK_CUR ) ) { + if( 0 != fseek( _file.get(), loc, SEEK_CUR ) ) { throw std::ios_base::failure( "cfile: " + _file_path.generic_string() + " unable to SEEK_CUR to: " + std::to_string(loc) ); } @@ -107,11 +98,10 @@ class cfile { if(!is_open()) throw std::ios_base::failure("cfile is not open"); - size_t result = fread( d, 1, n, _file_ptr ); - + size_t result = fread( d, 1, n, _file.get() ); if( result != n ) { throw std::ios_base::failure( "cfile: " + _file_path.generic_string() + - " unable to read " + std::to_string( n ) + " bytes; only read " + std::to_string( result ) ); + " unable to read " + std::to_string( n ) + " bytes; only read " + std::to_string( result ) ); } } @@ -119,11 +109,10 @@ class cfile { if(!is_open()) throw std::ios_base::failure("cfile is not open"); - size_t result = fwrite( d, 1, n, _file_ptr ); - + size_t result = fwrite( d, 1, n, _file.get() ); if( result != n ) { - throw std::ios_base::failure( "cfile: " + _file_path.generic_string() + - " unable to write " + std::to_string( n ) + " bytes; only wrote " + std::to_string( result ) ); + throw std::ios_base::failure( "cfile: " + _file_path.generic_string() + + " unable to write " + std::to_string( n ) + " bytes; only wrote " + std::to_string( result ) ); } } @@ -131,10 +120,10 @@ class cfile { if(!is_open()) throw std::ios_base::failure("cfile is not open"); - if( 0 != fflush( _file_ptr ) ) { - int ec = ferror( _file_ptr ); + if( 0 != fflush( _file.get() ) ) { + int ec = ferror( _file.get() ); throw std::ios_base::failure( "cfile: " + _file_path.generic_string() + - " unable to flush file, ferror: " + std::to_string( ec ) ); + " unable to flush file, ferror: " + std::to_string( ec ) ); } } @@ -142,54 +131,53 @@ class cfile { if(!is_open()) throw std::ios_base::failure("cfile is not open"); - const int fd = fileno(_file_ptr ); - + const int fd = fileno(_file.get() ); if( -1 == fd ) { throw std::ios_base::failure( "cfile: " + _file_path.generic_string() + - " unable to convert file pointer to file descriptor, error: " + - std::to_string( errno ) ); + " unable to convert file pointer to file descriptor, error: " + + std::to_string( errno ) ); } - if( -1 == fsync( fd ) ) { throw std::ios_base::failure( "cfile: " + _file_path.generic_string() + - " unable to sync file, error: " + std::to_string( errno ) ); + " unable to sync file, error: " + std::to_string( errno ) ); } } - bool eof() const { + bool eof() const { if(!is_open()) throw std::ios_base::failure("cfile is not open"); - if(feof(_file_ptr)) - return true; - } + return feof(_file.get()) != 0; + } int getc() { if(!is_open()) throw std::ios_base::failure("cfile is not open"); - int ret = fgetc(_file_ptr); - + int ret = fgetc(_file.get()); if (ret == EOF) { throw std::ios_base::failure( "cfile: " + _file_path.generic_string() + - " unable to read 1 byte"); + " unable to read 1 byte"); } return ret; } void close() { - if(is_open()) { - fclose(_file_ptr); - _open = false; - } + _file.reset(); + _open = false; } cfile_datastream create_datastream(); private: - bool _open; + cfile(const cfile &) = delete; + cfile(const cfile &&) = delete; + const cfile& operator=(const cfile &) = delete; + const cfile&& operator=(const cfile &&) = delete; + + bool _open = false; fc::path _file_path; - FILE *_file_ptr; + detail::unique_file _file; }; /* @@ -217,7 +205,12 @@ class cfile_datastream { size_t tellp() const { return cf.tellp(); } - private: +private: + cfile_datastream(const cfile_datastream &) = delete; + cfile_datastream(const cfile_datastream &&) = delete; + const cfile_datastream& operator=(const cfile_datastream &) = delete; + const cfile_datastream&& operator=(const cfile_datastream &&) = delete; + cfile& cf; }; @@ -227,8 +220,6 @@ inline cfile_datastream cfile::create_datastream() { template <> class datastream : public fc::cfile { -private: - char mCurrentChar = 'EOF'; public: using fc::cfile::cfile; @@ -236,16 +227,21 @@ class datastream : public fc::cfile { bool get(char& c) { c = this->getc(); - mCurrentChar = c; + _current_c = c; return true; } - bool remaining() const { - return (mCurrentChar != EOF); - } + bool remaining() { return (EOF != _current_c); } fc::cfile& storage() { return *this; } const fc::cfile& storage() const { return *this; } +private: + datastream(const datastream &) = delete; + datastream(const datastream &&) = delete; + const datastream& operator=(const datastream &) = delete; + const datastream&& operator=(const datastream &&) = delete; + + char _current_c = EOF; }; diff --git a/test/io/test_cfile.cpp b/test/io/test_cfile.cpp index fcae22b29..ff1844371 100644 --- a/test/io/test_cfile.cpp +++ b/test/io/test_cfile.cpp @@ -59,44 +59,44 @@ BOOST_AUTO_TEST_SUITE(cfile_test_suite) BOOST_CHECK( !fc::exists( tempdir.path() / "test") ); } - BOOST_AUTO_TEST_CASE(test_eof) - { - fc::temp_file tmpfile; - { - boost::filesystem::ofstream ofs(tmpfile.path()); - ofs << "the quick brown fox"; - } - - cfile t; - t.set_file_path(tmpfile.path()); - BOOST_CHECK_NO_THROW(t.open("r")); - BOOST_CHECK(t.is_open()); - BOOST_CHECK_NO_THROW(!t.eof()); - BOOST_CHECK_NO_THROW(t.getc() == 't'); - BOOST_CHECK_NO_THROW(t.skip(10)); - BOOST_CHECK_NO_THROW(!t.eof()); - BOOST_CHECK_NO_THROW(t.getc() == 'r'); - BOOST_CHECK_NO_THROW(t.skip(7)); - BOOST_CHECK_NO_THROW(t.eof()); - BOOST_CHECK_THROW(t.getc(), std::ios_base::failure); - - BOOST_CHECK_NO_THROW(t.open("r")); - BOOST_CHECK_NO_THROW(!t.eof()); - BOOST_CHECK_NO_THROW(t.skip(30)); - BOOST_CHECK_NO_THROW(t.eof()); - - BOOST_CHECK_NO_THROW(t.open("r")); - BOOST_CHECK_NO_THROW(!t.eof()); - BOOST_CHECK_THROW(t.skip(-2), std::ios_base::failure); - - BOOST_CHECK_NO_THROW(t.open("r")); - BOOST_CHECK_NO_THROW(!t.eof()); - BOOST_CHECK_NO_THROW(t.skip(4)); - BOOST_CHECK_NO_THROW(!t.eof()); - BOOST_CHECK_NO_THROW(t.getc() == 'q'); - BOOST_CHECK_NO_THROW(t.skip(19)); - BOOST_CHECK_NO_THROW(t.eof()); - BOOST_CHECK_THROW(t.seek(25), std::ios_base::failure); - } + BOOST_AUTO_TEST_CASE(test_eof) + { + fc::temp_file tmpfile; + { + boost::filesystem::ofstream ofs(tmpfile.path()); + ofs << "the quick brown fox"; + } + + cfile t; + t.set_file_path(tmpfile.path()); + BOOST_CHECK_NO_THROW(t.open("r")); + BOOST_CHECK(t.is_open()); + BOOST_CHECK_NO_THROW(!t.eof()); + BOOST_CHECK_NO_THROW(t.getc() == 't'); + BOOST_CHECK_NO_THROW(t.skip(10)); + BOOST_CHECK_NO_THROW(!t.eof()); + BOOST_CHECK_NO_THROW(t.getc() == 'r'); + BOOST_CHECK_NO_THROW(t.skip(7)); + BOOST_CHECK_NO_THROW(t.eof()); + BOOST_CHECK_THROW(t.getc(), std::ios_base::failure); + + BOOST_CHECK_NO_THROW(t.open("r")); + BOOST_CHECK_NO_THROW(!t.eof()); + BOOST_CHECK_NO_THROW(t.skip(30)); + BOOST_CHECK_NO_THROW(t.eof()); + + BOOST_CHECK_NO_THROW(t.open("r")); + BOOST_CHECK_NO_THROW(!t.eof()); + BOOST_CHECK_THROW(t.skip(-2), std::ios_base::failure); + + BOOST_CHECK_NO_THROW(t.open("r")); + BOOST_CHECK_NO_THROW(!t.eof()); + BOOST_CHECK_NO_THROW(t.skip(4)); + BOOST_CHECK_NO_THROW(!t.eof()); + BOOST_CHECK_NO_THROW(t.getc() == 'q'); + BOOST_CHECK_NO_THROW(t.skip(19)); + BOOST_CHECK_NO_THROW(t.eof()); + BOOST_CHECK_THROW(t.seek(25), std::ios_base::failure); + } BOOST_AUTO_TEST_SUITE_END() From fd7864e8b624fcc60ef41c5f06337ad36f4a1a1e Mon Sep 17 00:00:00 2001 From: James Folk Date: Thu, 4 Feb 2021 11:38:10 -0500 Subject: [PATCH 080/124] fixed the remaining function so that it checks if there is a byte to read and is not at the eof --- include/fc/io/cfile.hpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/include/fc/io/cfile.hpp b/include/fc/io/cfile.hpp index 7c2b23e8e..ed807807b 100644 --- a/include/fc/io/cfile.hpp +++ b/include/fc/io/cfile.hpp @@ -53,9 +53,22 @@ class cfile { if( !_file ) { throw std::ios_base::failure( "cfile unable to open: " + _file_path.generic_string() + " in mode: " + std::string( mode ) ); } + + fseek(_file.get(), 0L, SEEK_END); + _size = ftell(_file.get()); + fseek(_file.get(), 0L, SEEK_SET); + _open = true; } + bool remaining()const { + if(!is_open()) + throw std::ios_base::failure("cfile is not open"); + + return (ftell(_file.get()) < _size); + } + + size_t tellp() const { if(!is_open()) throw std::ios_base::failure("cfile is not open"); @@ -178,6 +191,7 @@ class cfile { bool _open = false; fc::path _file_path; detail::unique_file _file; + long _size; }; /* @@ -231,8 +245,6 @@ class datastream : public fc::cfile { return true; } - bool remaining() { return (EOF != _current_c); } - fc::cfile& storage() { return *this; } const fc::cfile& storage() const { return *this; } private: From a9c009cf2580b21d7b0c5f16e39b945b52066bc4 Mon Sep 17 00:00:00 2001 From: James Folk Date: Thu, 4 Feb 2021 12:53:30 -0500 Subject: [PATCH 081/124] updating the size if there was a write --- include/fc/io/cfile.hpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/include/fc/io/cfile.hpp b/include/fc/io/cfile.hpp index ed807807b..79218b045 100644 --- a/include/fc/io/cfile.hpp +++ b/include/fc/io/cfile.hpp @@ -119,14 +119,18 @@ class cfile { } void write( const char* d, size_t n ) { + const size_t WRITE_SIZE = 1; + if(!is_open()) throw std::ios_base::failure("cfile is not open"); - size_t result = fwrite( d, 1, n, _file.get() ); + size_t result = fwrite( d, WRITE_SIZE, n, _file.get() ); if( result != n ) { throw std::ios_base::failure( "cfile: " + _file_path.generic_string() + " unable to write " + std::to_string( n ) + " bytes; only wrote " + std::to_string( result ) ); } + // Keep up with the size of the file. + _size += (WRITE_SIZE * n); } void flush() { @@ -191,7 +195,7 @@ class cfile { bool _open = false; fc::path _file_path; detail::unique_file _file; - long _size; + size_t _size = 0; }; /* From f29c89e7bbd3fc0bb09f366f044886e0f5950a6a Mon Sep 17 00:00:00 2001 From: James Folk Date: Thu, 4 Feb 2021 13:09:30 -0500 Subject: [PATCH 082/124] removed the current_char as it is not needed anymore --- include/fc/io/cfile.hpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/include/fc/io/cfile.hpp b/include/fc/io/cfile.hpp index 79218b045..acd52d833 100644 --- a/include/fc/io/cfile.hpp +++ b/include/fc/io/cfile.hpp @@ -62,10 +62,7 @@ class cfile { } bool remaining()const { - if(!is_open()) - throw std::ios_base::failure("cfile is not open"); - - return (ftell(_file.get()) < _size); + return (tellp() < _size); } @@ -245,7 +242,6 @@ class datastream : public fc::cfile { bool get(char& c) { c = this->getc(); - _current_c = c; return true; } @@ -256,8 +252,6 @@ class datastream : public fc::cfile { datastream(const datastream &&) = delete; const datastream& operator=(const datastream &) = delete; const datastream&& operator=(const datastream &&) = delete; - - char _current_c = EOF; }; From 2e66fcd4300b1700afb5cc839e0d74b0839a1125 Mon Sep 17 00:00:00 2001 From: James Folk Date: Fri, 5 Feb 2021 10:44:42 -0500 Subject: [PATCH 083/124] removed the size check. fixed remaining function in cfile to work with multiple users --- include/fc/io/cfile.hpp | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/include/fc/io/cfile.hpp b/include/fc/io/cfile.hpp index acd52d833..b8bbebeff 100644 --- a/include/fc/io/cfile.hpp +++ b/include/fc/io/cfile.hpp @@ -54,18 +54,17 @@ class cfile { throw std::ios_base::failure( "cfile unable to open: " + _file_path.generic_string() + " in mode: " + std::string( mode ) ); } - fseek(_file.get(), 0L, SEEK_END); - _size = ftell(_file.get()); - fseek(_file.get(), 0L, SEEK_SET); _open = true; } - bool remaining()const { - return (tellp() < _size); + bool remaining(){ + int c(getc()); + bool isEOF(eof()); + ungetc(c, _file.get()); + return isEOF; } - size_t tellp() const { if(!is_open()) throw std::ios_base::failure("cfile is not open"); @@ -126,8 +125,6 @@ class cfile { throw std::ios_base::failure( "cfile: " + _file_path.generic_string() + " unable to write " + std::to_string( n ) + " bytes; only wrote " + std::to_string( result ) ); } - // Keep up with the size of the file. - _size += (WRITE_SIZE * n); } void flush() { @@ -192,7 +189,6 @@ class cfile { bool _open = false; fc::path _file_path; detail::unique_file _file; - size_t _size = 0; }; /* From fbad6f8f15881f5ea875c39dd44a97ae4abc48e1 Mon Sep 17 00:00:00 2001 From: James Folk Date: Fri, 5 Feb 2021 11:21:24 -0500 Subject: [PATCH 084/124] removed unused variable --- include/fc/io/cfile.hpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/include/fc/io/cfile.hpp b/include/fc/io/cfile.hpp index b8bbebeff..36f771ab8 100644 --- a/include/fc/io/cfile.hpp +++ b/include/fc/io/cfile.hpp @@ -59,6 +59,9 @@ class cfile { } bool remaining(){ + if(!is_open() || eof()) + return false; + int c(getc()); bool isEOF(eof()); ungetc(c, _file.get()); @@ -115,8 +118,6 @@ class cfile { } void write( const char* d, size_t n ) { - const size_t WRITE_SIZE = 1; - if(!is_open()) throw std::ios_base::failure("cfile is not open"); From dd48e11f35ffbbb69d8c31bd870d916372dd6263 Mon Sep 17 00:00:00 2001 From: James Folk Date: Fri, 5 Feb 2021 15:26:41 -0500 Subject: [PATCH 085/124] fixed a few errors --- include/fc/io/cfile.hpp | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/include/fc/io/cfile.hpp b/include/fc/io/cfile.hpp index 36f771ab8..5d3fb7f6d 100644 --- a/include/fc/io/cfile.hpp +++ b/include/fc/io/cfile.hpp @@ -62,9 +62,10 @@ class cfile { if(!is_open() || eof()) return false; - int c(getc()); - bool isEOF(eof()); + int c = getc(); + bool isEOF = eof(); ungetc(c, _file.get()); + return isEOF; } @@ -121,7 +122,7 @@ class cfile { if(!is_open()) throw std::ios_base::failure("cfile is not open"); - size_t result = fwrite( d, WRITE_SIZE, n, _file.get() ); + size_t result = fwrite( d, 1, n, _file.get() ); if( result != n ) { throw std::ios_base::failure( "cfile: " + _file_path.generic_string() + " unable to write " + std::to_string( n ) + " bytes; only wrote " + std::to_string( result ) ); @@ -183,9 +184,9 @@ class cfile { private: cfile(const cfile &) = delete; - cfile(const cfile &&) = delete; + cfile(cfile &&) = delete; const cfile& operator=(const cfile &) = delete; - const cfile&& operator=(const cfile &&) = delete; + cfile& operator=(cfile &&) = delete; bool _open = false; fc::path _file_path; @@ -219,9 +220,9 @@ class cfile_datastream { private: cfile_datastream(const cfile_datastream &) = delete; - cfile_datastream(const cfile_datastream &&) = delete; + cfile_datastream(cfile_datastream &&) = delete; const cfile_datastream& operator=(const cfile_datastream &) = delete; - const cfile_datastream&& operator=(const cfile_datastream &&) = delete; + cfile_datastream& operator=(cfile_datastream &&) = delete; cfile& cf; }; @@ -246,9 +247,9 @@ class datastream : public fc::cfile { const fc::cfile& storage() const { return *this; } private: datastream(const datastream &) = delete; - datastream(const datastream &&) = delete; + datastream(datastream &&) = delete; const datastream& operator=(const datastream &) = delete; - const datastream&& operator=(const datastream &&) = delete; + datastream& operator=(datastream &&) = delete; }; From 831566265597ec9385300f9ea31df5db4c2f7561 Mon Sep 17 00:00:00 2001 From: James Folk Date: Fri, 5 Feb 2021 15:59:59 -0500 Subject: [PATCH 086/124] error checking ungetc --- include/fc/io/cfile.hpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/include/fc/io/cfile.hpp b/include/fc/io/cfile.hpp index 5d3fb7f6d..80cce8ea3 100644 --- a/include/fc/io/cfile.hpp +++ b/include/fc/io/cfile.hpp @@ -64,7 +64,10 @@ class cfile { int c = getc(); bool isEOF = eof(); - ungetc(c, _file.get()); + int result = ungetc(c, _file.get()); + if(EOF == result) + throw std::ios_base::failure( "cfile: " + _file_path.generic_string() + + " unable to ungetc" ); return isEOF; } From b9266141b3fc3b932fb186c01af62d1dd1ecfc08 Mon Sep 17 00:00:00 2001 From: Matt Witherspoon <32485495+spoonincode@users.noreply.github.com> Date: Fri, 12 Feb 2021 14:16:46 -0500 Subject: [PATCH 087/124] remove BOOST_ASIO_HAS_LOCAL_SOCKETS ifdefs --- src/network/http/http_client.cpp | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/src/network/http/http_client.cpp b/src/network/http/http_client.cpp index 8233b8e07..34adb7b41 100644 --- a/src/network/http/http_client.cpp +++ b/src/network/http/http_client.cpp @@ -17,9 +17,7 @@ using tcp = boost::asio::ip::tcp; // from namespace http = boost::beast::http; // from namespace ssl = boost::asio::ssl; // from -#ifdef BOOST_ASIO_HAS_LOCAL_SOCKETS namespace local = boost::asio::local; -#endif namespace fc { @@ -36,14 +34,8 @@ class http_client_impl { using host_key = std::tuple; using raw_socket_ptr = std::unique_ptr; using ssl_socket_ptr = std::unique_ptr>; -#ifdef BOOST_ASIO_HAS_LOCAL_SOCKETS using unix_socket_ptr = std::unique_ptr; -#endif - using connection = std::variant; + using connection = std::variant; using connection_map = std::map; using unix_url_split_map = std::map; using error_code = boost::system::error_code; @@ -168,7 +160,6 @@ class http_client_impl { return std::make_tuple(dest.proto(), *dest.host(), port); } -#ifdef BOOST_ASIO_HAS_LOCAL_SOCKETS connection_map::iterator create_unix_connection( const url& dest, const deadline_type& deadline) { auto key = url_to_host_key(dest); auto socket = std::make_unique(_ioc); @@ -183,7 +174,6 @@ class http_client_impl { return res.first; } -#endif connection_map::iterator create_raw_connection( const url& dest, const deadline_type& deadline ) { auto key = url_to_host_key(dest); @@ -234,10 +224,8 @@ class http_client_impl { return create_raw_connection(dest, deadline); } else if (dest.proto() == "https") { return create_ssl_connection(dest, deadline); -#ifdef BOOST_ASIO_HAS_LOCAL_SOCKETS } else if (dest.proto() == "unix") { return create_unix_connection(dest, deadline); -#endif } else { FC_THROW("Unknown protocol ${proto}", ("proto", dest.proto())); } @@ -252,11 +240,9 @@ class http_client_impl { return !ptr->lowest_layer().is_open(); } -#ifdef BOOST_ASIO_HAS_LOCAL_SOCKETS bool operator() ( const unix_socket_ptr& ptr) const { return !ptr->is_open(); } -#endif }; bool check_closed( const connection_map::iterator& conn_itr ) { @@ -398,7 +384,6 @@ class http_client_impl { return result; } -#ifdef BOOST_ASIO_HAS_LOCAL_SOCKETS /* Unix URLs work a little special here. They'll originally be in the format of unix:///home/username/eosio-wallet/keosd.sock/v1/wallet/sign_digest @@ -433,7 +418,6 @@ class http_client_impl { url_path = "/" / url_path; return _unix_url_paths.emplace(full_url, fc::url("unix", socket_file.string(), ostring(), ostring(), url_path.string(), ostring(), ovariant_object(), std::optional())).first->second; } -#endif boost::asio::io_context _ioc; ssl::context _sslc; @@ -449,11 +433,9 @@ http_client::http_client() } variant http_client::post_sync(const url& dest, const variant& payload, const fc::time_point& deadline) { -#ifdef BOOST_ASIO_HAS_LOCAL_SOCKETS if(dest.proto() == "unix") return _my->post_sync(_my->get_unix_url(*dest.host()), payload, deadline); else -#endif return _my->post_sync(dest, payload, deadline); } From 03491cf5debb257f2ad8c5f2c80830839287bb4f Mon Sep 17 00:00:00 2001 From: Huang-Ming Huang Date: Fri, 19 Feb 2021 17:23:07 -0600 Subject: [PATCH 088/124] revert changes from PR 184 --- include/fc/io/cfile.hpp | 76 +++++------------------------------------ test/io/test_cfile.cpp | 41 ---------------------- 2 files changed, 9 insertions(+), 108 deletions(-) diff --git a/include/fc/io/cfile.hpp b/include/fc/io/cfile.hpp index 80cce8ea3..ec62e0ca4 100644 --- a/include/fc/io/cfile.hpp +++ b/include/fc/io/cfile.hpp @@ -30,11 +30,11 @@ class cfile { : _file(nullptr, &fclose) {} - void set_file_path( const fc::path& file_path ) { - _file_path = file_path; + void set_file_path( fc::path file_path ) { + _file_path = std::move( file_path ); } - const fc::path& get_file_path() const { + fc::path get_file_path() const { return _file_path; } @@ -53,29 +53,10 @@ class cfile { if( !_file ) { throw std::ios_base::failure( "cfile unable to open: " + _file_path.generic_string() + " in mode: " + std::string( mode ) ); } - - _open = true; } - bool remaining(){ - if(!is_open() || eof()) - return false; - - int c = getc(); - bool isEOF = eof(); - int result = ungetc(c, _file.get()); - if(EOF == result) - throw std::ios_base::failure( "cfile: " + _file_path.generic_string() + - " unable to ungetc" ); - - return isEOF; - } - size_t tellp() const { - if(!is_open()) - throw std::ios_base::failure("cfile is not open"); - long result = ftell( _file.get() ); if (result == -1) throw std::ios_base::failure("cfile: " + get_file_path().generic_string() + @@ -91,9 +72,6 @@ class cfile { } void seek_end( long loc ) { - if(!is_open()) - throw std::ios_base::failure("cfile is not open"); - if( 0 != fseek( _file.get(), loc, SEEK_END ) ) { throw std::ios_base::failure( "cfile: " + _file_path.generic_string() + " unable to SEEK_END to: " + std::to_string(loc) ); @@ -101,9 +79,6 @@ class cfile { } void skip( long loc) { - if(!is_open()) - throw std::ios_base::failure("cfile is not open"); - if( 0 != fseek( _file.get(), loc, SEEK_CUR ) ) { throw std::ios_base::failure( "cfile: " + _file_path.generic_string() + " unable to SEEK_CUR to: " + std::to_string(loc) ); @@ -111,9 +86,6 @@ class cfile { } void read( char* d, size_t n ) { - if(!is_open()) - throw std::ios_base::failure("cfile is not open"); - size_t result = fread( d, 1, n, _file.get() ); if( result != n ) { throw std::ios_base::failure( "cfile: " + _file_path.generic_string() + @@ -122,9 +94,6 @@ class cfile { } void write( const char* d, size_t n ) { - if(!is_open()) - throw std::ios_base::failure("cfile is not open"); - size_t result = fwrite( d, 1, n, _file.get() ); if( result != n ) { throw std::ios_base::failure( "cfile: " + _file_path.generic_string() + @@ -133,9 +102,6 @@ class cfile { } void flush() { - if(!is_open()) - throw std::ios_base::failure("cfile is not open"); - if( 0 != fflush( _file.get() ) ) { int ec = ferror( _file.get() ); throw std::ios_base::failure( "cfile: " + _file_path.generic_string() + @@ -144,9 +110,6 @@ class cfile { } void sync() { - if(!is_open()) - throw std::ios_base::failure("cfile is not open"); - const int fd = fileno(_file.get() ); if( -1 == fd ) { throw std::ios_base::failure( "cfile: " + _file_path.generic_string() + @@ -159,18 +122,10 @@ class cfile { } } - bool eof() const { - if(!is_open()) - throw std::ios_base::failure("cfile is not open"); - - return feof(_file.get()) != 0; - } - - int getc() { - if(!is_open()) - throw std::ios_base::failure("cfile is not open"); + bool eof() const { return feof(_file.get()) != 0; } - int ret = fgetc(_file.get()); + int getc() { + int ret = fgetc(_file.get()); if (ret == EOF) { throw std::ios_base::failure( "cfile: " + _file_path.generic_string() + " unable to read 1 byte"); @@ -186,11 +141,6 @@ class cfile { cfile_datastream create_datastream(); private: - cfile(const cfile &) = delete; - cfile(cfile &&) = delete; - const cfile& operator=(const cfile &) = delete; - cfile& operator=(cfile &&) = delete; - bool _open = false; fc::path _file_path; detail::unique_file _file; @@ -221,12 +171,7 @@ class cfile_datastream { size_t tellp() const { return cf.tellp(); } -private: - cfile_datastream(const cfile_datastream &) = delete; - cfile_datastream(cfile_datastream &&) = delete; - const cfile_datastream& operator=(const cfile_datastream &) = delete; - cfile_datastream& operator=(cfile_datastream &&) = delete; - + private: cfile& cf; }; @@ -246,13 +191,10 @@ class datastream : public fc::cfile { return true; } + bool remaining() { return !this->eof(); } + fc::cfile& storage() { return *this; } const fc::cfile& storage() const { return *this; } -private: - datastream(const datastream &) = delete; - datastream(datastream &&) = delete; - const datastream& operator=(const datastream &) = delete; - datastream& operator=(datastream &&) = delete; }; diff --git a/test/io/test_cfile.cpp b/test/io/test_cfile.cpp index ff1844371..f8c51360f 100644 --- a/test/io/test_cfile.cpp +++ b/test/io/test_cfile.cpp @@ -1,6 +1,5 @@ #define BOOST_TEST_MODULE io #include -#include #include @@ -59,44 +58,4 @@ BOOST_AUTO_TEST_SUITE(cfile_test_suite) BOOST_CHECK( !fc::exists( tempdir.path() / "test") ); } - BOOST_AUTO_TEST_CASE(test_eof) - { - fc::temp_file tmpfile; - { - boost::filesystem::ofstream ofs(tmpfile.path()); - ofs << "the quick brown fox"; - } - - cfile t; - t.set_file_path(tmpfile.path()); - BOOST_CHECK_NO_THROW(t.open("r")); - BOOST_CHECK(t.is_open()); - BOOST_CHECK_NO_THROW(!t.eof()); - BOOST_CHECK_NO_THROW(t.getc() == 't'); - BOOST_CHECK_NO_THROW(t.skip(10)); - BOOST_CHECK_NO_THROW(!t.eof()); - BOOST_CHECK_NO_THROW(t.getc() == 'r'); - BOOST_CHECK_NO_THROW(t.skip(7)); - BOOST_CHECK_NO_THROW(t.eof()); - BOOST_CHECK_THROW(t.getc(), std::ios_base::failure); - - BOOST_CHECK_NO_THROW(t.open("r")); - BOOST_CHECK_NO_THROW(!t.eof()); - BOOST_CHECK_NO_THROW(t.skip(30)); - BOOST_CHECK_NO_THROW(t.eof()); - - BOOST_CHECK_NO_THROW(t.open("r")); - BOOST_CHECK_NO_THROW(!t.eof()); - BOOST_CHECK_THROW(t.skip(-2), std::ios_base::failure); - - BOOST_CHECK_NO_THROW(t.open("r")); - BOOST_CHECK_NO_THROW(!t.eof()); - BOOST_CHECK_NO_THROW(t.skip(4)); - BOOST_CHECK_NO_THROW(!t.eof()); - BOOST_CHECK_NO_THROW(t.getc() == 'q'); - BOOST_CHECK_NO_THROW(t.skip(19)); - BOOST_CHECK_NO_THROW(t.eof()); - BOOST_CHECK_THROW(t.seek(25), std::ios_base::failure); - } - BOOST_AUTO_TEST_SUITE_END() From 3ccf0078b9b74fc62a5909e0656104e389e47e6f Mon Sep 17 00:00:00 2001 From: Huang-Ming Huang Date: Fri, 19 Feb 2021 17:29:07 -0600 Subject: [PATCH 089/124] avoid datastream to be used for unpack --- include/fc/io/cfile.hpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/include/fc/io/cfile.hpp b/include/fc/io/cfile.hpp index ec62e0ca4..74723a144 100644 --- a/include/fc/io/cfile.hpp +++ b/include/fc/io/cfile.hpp @@ -179,6 +179,11 @@ inline cfile_datastream cfile::create_datastream() { return cfile_datastream(*this); } +/* + * @brief datastream adapter that adapts cfile for use with fc pack + * + * This class supports pack functionality but not unpack. + */ template <> class datastream : public fc::cfile { public: @@ -191,8 +196,6 @@ class datastream : public fc::cfile { return true; } - bool remaining() { return !this->eof(); } - fc::cfile& storage() { return *this; } const fc::cfile& storage() const { return *this; } }; From 29ebe66248fb23b07f3fef265ac770d50d39a576 Mon Sep 17 00:00:00 2001 From: Matt Witherspoon <32485495+spoonincode@users.noreply.github.com> Date: Tue, 27 Apr 2021 13:35:19 -0400 Subject: [PATCH 090/124] remvove uneeded Boost_LIBRARIES linkage from webauthn test --- test/crypto/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/crypto/CMakeLists.txt b/test/crypto/CMakeLists.txt index c625a8e88..c293ed2ea 100644 --- a/test/crypto/CMakeLists.txt +++ b/test/crypto/CMakeLists.txt @@ -2,7 +2,7 @@ add_executable( test_cypher_suites test_cypher_suites.cpp ) target_link_libraries( test_cypher_suites fc ) add_executable( test_webauthn test_webauthn.cpp ) -target_link_libraries( test_webauthn fc ${Boost_LIBRARIES}) +target_link_libraries( test_webauthn fc ) add_test(NAME test_cypher_suites COMMAND libraries/fc/test/crypto/test_cypher_suites WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) add_test(NAME test_webauthn COMMAND libraries/fc/test/crypto/test_webauthn WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) \ No newline at end of file From 7334ec86434ca7aee3e8676c453b093a9caa8966 Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Fri, 30 Apr 2021 08:04:16 -0500 Subject: [PATCH 091/124] Do not limit write to uint32_t size --- include/fc/io/datastream.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/fc/io/datastream.hpp b/include/fc/io/datastream.hpp index 0da6c98d4..7306f0622 100644 --- a/include/fc/io/datastream.hpp +++ b/include/fc/io/datastream.hpp @@ -42,7 +42,7 @@ class datastream || std::is_same_v< } inline bool write( const char* d, size_t s ) { - if( _end - _pos >= (int32_t)s ) { + if( size_t(_end - _pos) >= (size_t)s ) { memcpy( _pos, d, s ); _pos += s; return true; From 7fb5c3309ae93857adbffe4161fab504e5908626 Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Thu, 27 May 2021 07:34:27 -0500 Subject: [PATCH 092/124] Switch to variadic template --- include/fc/fwd.hpp | 6 ++---- include/fc/fwd_impl.hpp | 26 +++----------------------- 2 files changed, 5 insertions(+), 27 deletions(-) diff --git a/include/fc/fwd.hpp b/include/fc/fwd.hpp index 33488d28a..0aabe43a8 100644 --- a/include/fc/fwd.hpp +++ b/include/fc/fwd.hpp @@ -10,10 +10,8 @@ namespace fc { template class fwd { public: - template fwd( U&& u ); - template fwd( U&& u, V&& v ); - template fwd( U&& u, V&& v, X&& x); - template fwd( U&& u, V&& v, X&& x, Y&& y); + template + fwd( U&&... u ); fwd(); fwd( const fwd& f ); diff --git a/include/fc/fwd_impl.hpp b/include/fc/fwd_impl.hpp index 041e16989..af2b23fdd 100644 --- a/include/fc/fwd_impl.hpp +++ b/include/fc/fwd_impl.hpp @@ -58,32 +58,12 @@ namespace fc { void check_size() { static_assert( (ProvidedSize >= RequiredSize), "Failed to reserve enough space in fc::fwd" ); } template - template - fwd::fwd( U&& u ) { - check_size(); - new (this) T( fc::forward(u) ); - } - - template - template - fwd::fwd( U&& u, V&& v ) { - check_size(); - new (this) T( fc::forward(u), fc::forward(v) ); - } - template - template - fwd::fwd( U&& u, V&& v, X&& x ) { - check_size(); - new (this) T( fc::forward(u), fc::forward(v), fc::forward(x) ); - } - template - template - fwd::fwd( U&& u, V&& v, X&& x, Y&& y ) { + template + fwd::fwd( U&&... u ) { check_size(); - new (this) T( fc::forward(u), fc::forward(v), fc::forward(x), fc::forward(y) ); + new (this) T( fc::forward(u)... ); } - template fwd::fwd() { check_size(); From dc7df626f73ed093de8785c124bf3eec7f4f87c5 Mon Sep 17 00:00:00 2001 From: Jingjun Zhao Date: Mon, 14 Jun 2021 10:02:12 -0400 Subject: [PATCH 093/124] Add a log message when zipkin is connected --- src/log/zipkin.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/log/zipkin.cpp b/src/log/zipkin.cpp index eddf4d41d..228db4cb7 100644 --- a/src/log/zipkin.cpp +++ b/src/log/zipkin.cpp @@ -12,6 +12,8 @@ #include #include +#include + namespace fc { zipkin_config& zipkin_config::get() { @@ -53,6 +55,7 @@ class zipkin::impl { std::mutex mtx; uint64_t next_id = 0; http_client http; + bool connected = false; std::atomic consecutive_errors = 0; std::atomic stopped = 0; std::optional endpoint; @@ -178,6 +181,10 @@ void zipkin::impl::log( zipkin_span::span_data&& span ) { http.post_sync( *endpoint, create_zipkin_variant( std::move( span ), service_name ), deadline ); consecutive_errors = 0; + if (!connected){ + connected = true; + ilog("connected to zipkin: ${u}", ("u", zipkin_url)); + } return; } catch( const fc::exception& e ) { wlog( "unable to connect to zipkin: ${u}, error: ${e}", ("u", zipkin_url)("e", e.to_detail_string()) ); @@ -187,6 +194,7 @@ void zipkin::impl::log( zipkin_span::span_data&& span ) { wlog( "unable to connect to zipkin: ${u}, error: unknown", ("u", zipkin_url) ); } ++consecutive_errors; + connected = false; } uint64_t zipkin_span::to_id( const fc::sha256& id ) { From b23635c8b273d63c665e5097d0029ea172c95e0e Mon Sep 17 00:00:00 2001 From: Jingjun Zhao Date: Mon, 14 Jun 2021 10:15:58 -0400 Subject: [PATCH 094/124] Retry connecting to zipkin every 30 seconds --- src/log/zipkin.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/log/zipkin.cpp b/src/log/zipkin.cpp index 228db4cb7..21557fa24 100644 --- a/src/log/zipkin.cpp +++ b/src/log/zipkin.cpp @@ -12,8 +12,6 @@ #include #include -#include - namespace fc { zipkin_config& zipkin_config::get() { @@ -195,6 +193,7 @@ void zipkin::impl::log( zipkin_span::span_data&& span ) { } ++consecutive_errors; connected = false; + sleep(30); } uint64_t zipkin_span::to_id( const fc::sha256& id ) { From e3c3be71851bd9b989c9254e306694914ba6a46b Mon Sep 17 00:00:00 2001 From: Jingjun Zhao Date: Mon, 14 Jun 2021 23:14:00 -0400 Subject: [PATCH 095/124] Process SIGHUP to enable zipkin_appender --- include/fc/log/zipkin.hpp | 6 ++++++ src/log/zipkin.cpp | 22 +++++++++++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/include/fc/log/zipkin.hpp b/include/fc/log/zipkin.hpp index 32010a114..cade326b5 100644 --- a/include/fc/log/zipkin.hpp +++ b/include/fc/log/zipkin.hpp @@ -45,6 +45,11 @@ class zipkin_config { /// Starts with a random id and increments on each call, will not return 0 static uint64_t get_next_unique_id(); + /// Handle SIGHUP signal + static void handle_sighup(); + static void reset_sighup(); + static bool check_sighup(); + private: /// Provide access to initialized zipkin endpoint /// Thread safe as long as init() called correctly @@ -55,6 +60,7 @@ class zipkin_config { private: std::unique_ptr zip; + static bool received_sighup; }; struct zipkin_span { diff --git a/src/log/zipkin.cpp b/src/log/zipkin.cpp index 21557fa24..1e55a93fe 100644 --- a/src/log/zipkin.cpp +++ b/src/log/zipkin.cpp @@ -14,6 +14,8 @@ namespace fc { +bool zipkin_config::received_sighup = false; + zipkin_config& zipkin_config::get() { static zipkin_config the_one; return the_one; @@ -43,6 +45,18 @@ uint64_t zipkin_config::get_next_unique_id() { return get().zip->get_next_unique_id(); } +void zipkin_config::handle_sighup(){ + received_sighup = true; +} + +void zipkin_config::reset_sighup(){ + received_sighup = false; +} + +bool zipkin_config::check_sighup(){ + return received_sighup; +} + class zipkin::impl { public: static constexpr uint32_t max_consecutive_errors = 9; @@ -157,8 +171,14 @@ fc::variant create_zipkin_variant( zipkin_span::span_data&& span, const std::str } void zipkin::log( zipkin_span::span_data&& span ) { - if( my->consecutive_errors > my->max_consecutive_errors || my->stopped ) + if (my->stopped) { return; + } else if(zipkin_config::check_sighup()) { + zipkin_config::reset_sighup(); + my->consecutive_errors = 0; + } else if(my->consecutive_errors > my->max_consecutive_errors) { + return; + } boost::asio::post(my->work_strand, [this, span{std::move(span)}]() mutable { my->log( std::move( span ) ); From 66bb5f2eb8baa2478d23b265899657c6ac472a57 Mon Sep 17 00:00:00 2001 From: Jingjun Zhao Date: Wed, 16 Jun 2021 15:00:59 -0400 Subject: [PATCH 096/124] Move sleep(30) into the calling thread of post --- src/log/zipkin.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/log/zipkin.cpp b/src/log/zipkin.cpp index 1e55a93fe..7ddd85f23 100644 --- a/src/log/zipkin.cpp +++ b/src/log/zipkin.cpp @@ -180,6 +180,10 @@ void zipkin::log( zipkin_span::span_data&& span ) { return; } + if (my->consecutive_errors > 0){ + sleep(30); + } + boost::asio::post(my->work_strand, [this, span{std::move(span)}]() mutable { my->log( std::move( span ) ); }); @@ -213,7 +217,6 @@ void zipkin::impl::log( zipkin_span::span_data&& span ) { } ++consecutive_errors; connected = false; - sleep(30); } uint64_t zipkin_span::to_id( const fc::sha256& id ) { From 5b493acf550c66ad5f8c743a34ff2f79807944cb Mon Sep 17 00:00:00 2001 From: Jingjun Zhao Date: Thu, 17 Jun 2021 00:08:20 -0400 Subject: [PATCH 097/124] Make handling SIGHUP signal code thread safe --- include/fc/log/zipkin.hpp | 10 ++++++---- src/log/zipkin.cpp | 29 ++++++++++++++++------------- 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/include/fc/log/zipkin.hpp b/include/fc/log/zipkin.hpp index cade326b5..fd07b4f73 100644 --- a/include/fc/log/zipkin.hpp +++ b/include/fc/log/zipkin.hpp @@ -45,10 +45,8 @@ class zipkin_config { /// Starts with a random id and increments on each call, will not return 0 static uint64_t get_next_unique_id(); - /// Handle SIGHUP signal + /// Handle SIGHUP signal forwarded from net_plugin static void handle_sighup(); - static void reset_sighup(); - static bool check_sighup(); private: /// Provide access to initialized zipkin endpoint @@ -60,7 +58,6 @@ class zipkin_config { private: std::unique_ptr zip; - static bool received_sighup; }; struct zipkin_span { @@ -194,9 +191,14 @@ class zipkin { // Logs zipkin json via http on separate thread void log( zipkin_span::span_data&& span ); + void on_sighup_flag(); + void off_sighup_flag(); + bool is_sighup_flag_on() const { return sighup_flag; }; + private: class impl; std::unique_ptr my; + bool sighup_flag; }; } // namespace fc diff --git a/src/log/zipkin.cpp b/src/log/zipkin.cpp index 7ddd85f23..b6de79bf9 100644 --- a/src/log/zipkin.cpp +++ b/src/log/zipkin.cpp @@ -14,8 +14,6 @@ namespace fc { -bool zipkin_config::received_sighup = false; - zipkin_config& zipkin_config::get() { static zipkin_config the_one; return the_one; @@ -46,15 +44,10 @@ uint64_t zipkin_config::get_next_unique_id() { } void zipkin_config::handle_sighup(){ - received_sighup = true; -} - -void zipkin_config::reset_sighup(){ - received_sighup = false; -} - -bool zipkin_config::check_sighup(){ - return received_sighup; + if( !get().zip ) { + FC_THROW_EXCEPTION(fc::assert_exception, "uninitialized zipkin"); + } + get().zip->on_sighup_flag(); } class zipkin::impl { @@ -133,6 +126,16 @@ void zipkin::shutdown() { my->shutdown(); } +void zipkin::on_sighup_flag() { + std::scoped_lock g( my->mtx ); + sighup_flag = true; +} + +void zipkin::off_sighup_flag() { + std::scoped_lock g( my->mtx ); + sighup_flag = false; +} + fc::variant create_zipkin_variant( zipkin_span::span_data&& span, const std::string& service_name ) { // https://zipkin.io/zipkin-api/ // std::string traceId; // [a-f0-9]{16,32} unique id for trace, all children spans shared same id @@ -173,8 +176,8 @@ fc::variant create_zipkin_variant( zipkin_span::span_data&& span, const std::str void zipkin::log( zipkin_span::span_data&& span ) { if (my->stopped) { return; - } else if(zipkin_config::check_sighup()) { - zipkin_config::reset_sighup(); + } else if( is_sighup_flag_on() ) { + off_sighup_flag(); my->consecutive_errors = 0; } else if(my->consecutive_errors > my->max_consecutive_errors) { return; From 2394a54dc5873d8e4e93ad796c7fdded2b34756b Mon Sep 17 00:00:00 2001 From: Jingjun Zhao Date: Thu, 17 Jun 2021 08:33:26 -0400 Subject: [PATCH 098/124] Update the method handling SIGHUP signal --- src/log/zipkin.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/log/zipkin.cpp b/src/log/zipkin.cpp index b6de79bf9..ff1675d54 100644 --- a/src/log/zipkin.cpp +++ b/src/log/zipkin.cpp @@ -44,10 +44,9 @@ uint64_t zipkin_config::get_next_unique_id() { } void zipkin_config::handle_sighup(){ - if( !get().zip ) { - FC_THROW_EXCEPTION(fc::assert_exception, "uninitialized zipkin"); + if( get().zip ) { + get().zip->on_sighup_flag(); } - get().zip->on_sighup_flag(); } class zipkin::impl { From e4b425391f4b01f7464620e768fe5d6be6d836ce Mon Sep 17 00:00:00 2001 From: Jingjun Zhao Date: Thu, 17 Jun 2021 16:54:22 -0400 Subject: [PATCH 099/124] Use a timer instead of sleep to avoid main thread being blocked --- include/fc/log/zipkin.hpp | 6 ++++-- src/log/zipkin.cpp | 40 +++++++++++++++++++++++++++++---------- 2 files changed, 34 insertions(+), 12 deletions(-) diff --git a/include/fc/log/zipkin.hpp b/include/fc/log/zipkin.hpp index fd07b4f73..5ca842c9a 100644 --- a/include/fc/log/zipkin.hpp +++ b/include/fc/log/zipkin.hpp @@ -45,7 +45,7 @@ class zipkin_config { /// Starts with a random id and increments on each call, will not return 0 static uint64_t get_next_unique_id(); - /// Handle SIGHUP signal forwarded from net_plugin + /// Handle SIGHUP signal static void handle_sighup(); private: @@ -191,10 +191,12 @@ class zipkin { // Logs zipkin json via http on separate thread void log( zipkin_span::span_data&& span ); + /// thread safe void on_sighup_flag(); void off_sighup_flag(); - bool is_sighup_flag_on() const { return sighup_flag; }; + bool is_sighup_flag_on() const; + void post_request(zipkin_span::span_data&& span); private: class impl; std::unique_ptr my; diff --git a/src/log/zipkin.cpp b/src/log/zipkin.cpp index ff1675d54..d11967453 100644 --- a/src/log/zipkin.cpp +++ b/src/log/zipkin.cpp @@ -60,11 +60,13 @@ class zipkin::impl { uint64_t next_id = 0; http_client http; bool connected = false; + bool timer_expired = true; std::atomic consecutive_errors = 0; std::atomic stopped = 0; std::optional endpoint; std::thread thread; boost::asio::io_context ctx; + boost::asio::deadline_timer timer{ctx}; boost::asio::io_context::strand work_strand{ctx}; boost::asio::executor_work_guard work_guard = boost::asio::make_work_guard(ctx); @@ -135,6 +137,12 @@ void zipkin::off_sighup_flag() { sighup_flag = false; } +bool zipkin::is_sighup_flag_on() const +{ + std::scoped_lock g( my->mtx ); + return sighup_flag; +} + fc::variant create_zipkin_variant( zipkin_span::span_data&& span, const std::string& service_name ) { // https://zipkin.io/zipkin-api/ // std::string traceId; // [a-f0-9]{16,32} unique id for trace, all children spans shared same id @@ -172,23 +180,35 @@ fc::variant create_zipkin_variant( zipkin_span::span_data&& span, const std::str return result; } +void zipkin::post_request(zipkin_span::span_data&& span) { + boost::asio::post(my->work_strand, [this, span{std::move(span)}]() mutable { + my->log( std::move( span ) ); + }); +} + void zipkin::log( zipkin_span::span_data&& span ) { - if (my->stopped) { + if( my->stopped ) { return; - } else if( is_sighup_flag_on() ) { + }else if( is_sighup_flag_on() ) { off_sighup_flag(); my->consecutive_errors = 0; - } else if(my->consecutive_errors > my->max_consecutive_errors) { + }else if( my->consecutive_errors > my->max_consecutive_errors ) { return; } - if (my->consecutive_errors > 0){ - sleep(30); + if( my->consecutive_errors > 0 ) { + if( my->timer_expired ) { + my->timer_expired = false; + my->timer.expires_from_now(boost::posix_time::seconds(30)); + my->timer.async_wait([this, span{std::move(span)}](auto&) { + ilog("Retry connecting to zipkin: ${u} ...", ("u", my->zipkin_url) ); + post_request(const_cast(span)); + my->timer_expired = true; + }); + } + }else { + post_request(std::move(span)); } - - boost::asio::post(my->work_strand, [this, span{std::move(span)}]() mutable { - my->log( std::move( span ) ); - }); } void zipkin::impl::log( zipkin_span::span_data&& span ) { @@ -207,7 +227,7 @@ void zipkin::impl::log( zipkin_span::span_data&& span ) { consecutive_errors = 0; if (!connected){ connected = true; - ilog("connected to zipkin: ${u}", ("u", zipkin_url)); + ilog("Connected to zipkin: ${u}", ("u", zipkin_url)); } return; } catch( const fc::exception& e ) { From 218e261c943182dd13dd99a7a63edc8133789ee1 Mon Sep 17 00:00:00 2001 From: Jingjun Zhao Date: Thu, 17 Jun 2021 23:55:36 -0400 Subject: [PATCH 100/124] Update the handler of asynchronous wait on the timer --- src/log/zipkin.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/log/zipkin.cpp b/src/log/zipkin.cpp index d11967453..d3fe34e40 100644 --- a/src/log/zipkin.cpp +++ b/src/log/zipkin.cpp @@ -200,9 +200,9 @@ void zipkin::log( zipkin_span::span_data&& span ) { if( my->timer_expired ) { my->timer_expired = false; my->timer.expires_from_now(boost::posix_time::seconds(30)); - my->timer.async_wait([this, span{std::move(span)}](auto&) { + my->timer.async_wait([this, span{std::move(span)}](auto&) mutable { ilog("Retry connecting to zipkin: ${u} ...", ("u", my->zipkin_url) ); - post_request(const_cast(span)); + post_request(std::move(span)); my->timer_expired = true; }); } From c47902c1727500934210c862319ce43f2c390793 Mon Sep 17 00:00:00 2001 From: Jingjun Zhao Date: Fri, 18 Jun 2021 16:51:15 -0400 Subject: [PATCH 101/124] Make method handle_sighup() signal safe --- include/fc/log/zipkin.hpp | 11 ++++------- src/log/zipkin.cpp | 31 ++++++++++--------------------- 2 files changed, 14 insertions(+), 28 deletions(-) diff --git a/include/fc/log/zipkin.hpp b/include/fc/log/zipkin.hpp index 5ca842c9a..f08303c69 100644 --- a/include/fc/log/zipkin.hpp +++ b/include/fc/log/zipkin.hpp @@ -45,7 +45,8 @@ class zipkin_config { /// Starts with a random id and increments on each call, will not return 0 static uint64_t get_next_unique_id(); - /// Handle SIGHUP signal + /// Signal safe + /// This is not called directly from the SIGHUP signal handler in the main thread static void handle_sighup(); private: @@ -191,16 +192,12 @@ class zipkin { // Logs zipkin json via http on separate thread void log( zipkin_span::span_data&& span ); - /// thread safe - void on_sighup_flag(); - void off_sighup_flag(); - bool is_sighup_flag_on() const; - + // Post http request to the boost asio queue void post_request(zipkin_span::span_data&& span); + private: class impl; std::unique_ptr my; - bool sighup_flag; }; } // namespace fc diff --git a/src/log/zipkin.cpp b/src/log/zipkin.cpp index d3fe34e40..c57ed721c 100644 --- a/src/log/zipkin.cpp +++ b/src/log/zipkin.cpp @@ -14,6 +14,11 @@ namespace fc { +//signal safe +volatile sig_atomic_t do_sighup = 0; +//thread safe +std::atomic sighup_requested = false; + zipkin_config& zipkin_config::get() { static zipkin_config the_one; return the_one; @@ -44,9 +49,8 @@ uint64_t zipkin_config::get_next_unique_id() { } void zipkin_config::handle_sighup(){ - if( get().zip ) { - get().zip->on_sighup_flag(); - } + fc::do_sighup = 1; + fc::sighup_requested = true; } class zipkin::impl { @@ -127,22 +131,6 @@ void zipkin::shutdown() { my->shutdown(); } -void zipkin::on_sighup_flag() { - std::scoped_lock g( my->mtx ); - sighup_flag = true; -} - -void zipkin::off_sighup_flag() { - std::scoped_lock g( my->mtx ); - sighup_flag = false; -} - -bool zipkin::is_sighup_flag_on() const -{ - std::scoped_lock g( my->mtx ); - return sighup_flag; -} - fc::variant create_zipkin_variant( zipkin_span::span_data&& span, const std::string& service_name ) { // https://zipkin.io/zipkin-api/ // std::string traceId; // [a-f0-9]{16,32} unique id for trace, all children spans shared same id @@ -189,8 +177,9 @@ void zipkin::post_request(zipkin_span::span_data&& span) { void zipkin::log( zipkin_span::span_data&& span ) { if( my->stopped ) { return; - }else if( is_sighup_flag_on() ) { - off_sighup_flag(); + }else if( fc::do_sighup && fc::sighup_requested.load()) { + do_sighup = 0; + fc::sighup_requested = false; my->consecutive_errors = 0; }else if( my->consecutive_errors > my->max_consecutive_errors ) { return; From 6e3ff704bd777d358db2528ccfd9c52b1e64413a Mon Sep 17 00:00:00 2001 From: Jingjun Zhao Date: Fri, 18 Jun 2021 17:15:39 -0400 Subject: [PATCH 102/124] Add scope operator to an atomic var --- src/log/zipkin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/log/zipkin.cpp b/src/log/zipkin.cpp index c57ed721c..a38904800 100644 --- a/src/log/zipkin.cpp +++ b/src/log/zipkin.cpp @@ -178,7 +178,7 @@ void zipkin::log( zipkin_span::span_data&& span ) { if( my->stopped ) { return; }else if( fc::do_sighup && fc::sighup_requested.load()) { - do_sighup = 0; + fc::do_sighup = 0; fc::sighup_requested = false; my->consecutive_errors = 0; }else if( my->consecutive_errors > my->max_consecutive_errors ) { From 3545c92b3a8d5f4cca3949424ad6dd72e6f27e7c Mon Sep 17 00:00:00 2001 From: Jingjun Zhao Date: Thu, 24 Jun 2021 14:02:21 -0400 Subject: [PATCH 103/124] Make var timer_expired thread safe --- include/fc/log/zipkin.hpp | 2 +- src/log/zipkin.cpp | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/include/fc/log/zipkin.hpp b/include/fc/log/zipkin.hpp index f08303c69..e5917f069 100644 --- a/include/fc/log/zipkin.hpp +++ b/include/fc/log/zipkin.hpp @@ -46,7 +46,7 @@ class zipkin_config { static uint64_t get_next_unique_id(); /// Signal safe - /// This is not called directly from the SIGHUP signal handler in the main thread + /// This is not called directly from the SIGHUP signal handler static void handle_sighup(); private: diff --git a/src/log/zipkin.cpp b/src/log/zipkin.cpp index a38904800..b16d64200 100644 --- a/src/log/zipkin.cpp +++ b/src/log/zipkin.cpp @@ -64,7 +64,8 @@ class zipkin::impl { uint64_t next_id = 0; http_client http; bool connected = false; - bool timer_expired = true; + // thread safe + std::atomic timer_expired = true; std::atomic consecutive_errors = 0; std::atomic stopped = 0; std::optional endpoint; From 4e992642c1921d12944e07064b02d178eb346f06 Mon Sep 17 00:00:00 2001 From: Jingjun Zhao Date: Thu, 24 Jun 2021 15:56:31 -0400 Subject: [PATCH 104/124] Remove unneeded comment --- include/fc/log/zipkin.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/include/fc/log/zipkin.hpp b/include/fc/log/zipkin.hpp index e5917f069..1a1de7b9e 100644 --- a/include/fc/log/zipkin.hpp +++ b/include/fc/log/zipkin.hpp @@ -46,7 +46,6 @@ class zipkin_config { static uint64_t get_next_unique_id(); /// Signal safe - /// This is not called directly from the SIGHUP signal handler static void handle_sighup(); private: From 36ecb2b120fcbf4ae72258fc1f440812f2b292c0 Mon Sep 17 00:00:00 2001 From: Jingjun Zhao Date: Thu, 24 Jun 2021 19:07:16 -0400 Subject: [PATCH 105/124] Redefine a var as atomic_flag so it is signal safe, thread atomic and lock free --- src/log/zipkin.cpp | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/log/zipkin.cpp b/src/log/zipkin.cpp index b16d64200..2c2a934c0 100644 --- a/src/log/zipkin.cpp +++ b/src/log/zipkin.cpp @@ -14,10 +14,8 @@ namespace fc { -//signal safe -volatile sig_atomic_t do_sighup = 0; -//thread safe -std::atomic sighup_requested = false; +// signal safe, thread atomic and lock free +std::atomic_flag do_sighup = ATOMIC_FLAG_INIT; zipkin_config& zipkin_config::get() { static zipkin_config the_one; @@ -49,8 +47,7 @@ uint64_t zipkin_config::get_next_unique_id() { } void zipkin_config::handle_sighup(){ - fc::do_sighup = 1; - fc::sighup_requested = true; + fc::do_sighup.test_and_set(); } class zipkin::impl { @@ -178,14 +175,16 @@ void zipkin::post_request(zipkin_span::span_data&& span) { void zipkin::log( zipkin_span::span_data&& span ) { if( my->stopped ) { return; - }else if( fc::do_sighup && fc::sighup_requested.load()) { - fc::do_sighup = 0; - fc::sighup_requested = false; + }else if( fc::do_sighup.test_and_set()) { // member func .test() is not available until c++20. + fc::do_sighup.clear(); my->consecutive_errors = 0; }else if( my->consecutive_errors > my->max_consecutive_errors ) { + fc::do_sighup.clear(); // reverse test_and_set() return; } + fc::do_sighup.clear(); // reverse test_and_set() + if( my->consecutive_errors > 0 ) { if( my->timer_expired ) { my->timer_expired = false; From d6912ceff71bb73c5633840de7cab3a2b2852f99 Mon Sep 17 00:00:00 2001 From: Jingjun Zhao Date: Mon, 28 Jun 2021 14:12:22 -0400 Subject: [PATCH 106/124] Revert last commit that can cause a race condition --- src/log/zipkin.cpp | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/log/zipkin.cpp b/src/log/zipkin.cpp index 2c2a934c0..a8434446e 100644 --- a/src/log/zipkin.cpp +++ b/src/log/zipkin.cpp @@ -14,8 +14,7 @@ namespace fc { -// signal safe, thread atomic and lock free -std::atomic_flag do_sighup = ATOMIC_FLAG_INIT; +std::atomic sighup_requested = false; zipkin_config& zipkin_config::get() { static zipkin_config the_one; @@ -47,7 +46,8 @@ uint64_t zipkin_config::get_next_unique_id() { } void zipkin_config::handle_sighup(){ - fc::do_sighup.test_and_set(); + static_assert(std::atomic::is_always_lock_free == true, "expected a lock-free atomic type"); + fc::sighup_requested = true; } class zipkin::impl { @@ -175,16 +175,13 @@ void zipkin::post_request(zipkin_span::span_data&& span) { void zipkin::log( zipkin_span::span_data&& span ) { if( my->stopped ) { return; - }else if( fc::do_sighup.test_and_set()) { // member func .test() is not available until c++20. - fc::do_sighup.clear(); + }else if( fc::sighup_requested.load()) { + fc::sighup_requested = false; my->consecutive_errors = 0; }else if( my->consecutive_errors > my->max_consecutive_errors ) { - fc::do_sighup.clear(); // reverse test_and_set() return; } - fc::do_sighup.clear(); // reverse test_and_set() - if( my->consecutive_errors > 0 ) { if( my->timer_expired ) { my->timer_expired = false; From 1d15fda9ec74ed795d50c6e9fc5f80919ed64329 Mon Sep 17 00:00:00 2001 From: Jingjun Zhao Date: Mon, 28 Jun 2021 17:54:48 -0400 Subject: [PATCH 107/124] Add a new option retry_interval_us --- include/fc/log/zipkin.hpp | 5 +++-- src/log/zipkin.cpp | 16 +++++++++------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/include/fc/log/zipkin.hpp b/include/fc/log/zipkin.hpp index 1a1de7b9e..052c0bfe0 100644 --- a/include/fc/log/zipkin.hpp +++ b/include/fc/log/zipkin.hpp @@ -32,7 +32,8 @@ class zipkin_config { /// @param url the url endpoint of zipkin server. e.g. http://127.0.0.1:9411/api/v2/spans /// @param service_name the service name to include in each zipkin span /// @param timeout_us the timeout in microseconds for each http call (9 consecutive failures and zipkin is disabled) - static void init( const std::string& url, const std::string& service_name, uint32_t timeout_us ); + /// @param retry_interval_us the interval in microseconds for connecting to zipkin + static void init( const std::string& url, const std::string& service_name, uint32_t timeout_us, uint32_t retry_interval_us ); /// Thread safe only if init() called from main thread before spawning of any threads /// @throw assert_exception if called before init() @@ -177,7 +178,7 @@ struct optional_trace { class zipkin { public: - zipkin( const std::string& url, const std::string& service_name, uint32_t timeout_us ); + zipkin( const std::string& url, const std::string& service_name, uint32_t timeout_us, uint32_t retry_interval_us ); /// finishes logging all queued up spans ~zipkin() = default; diff --git a/src/log/zipkin.cpp b/src/log/zipkin.cpp index a8434446e..5506f6595 100644 --- a/src/log/zipkin.cpp +++ b/src/log/zipkin.cpp @@ -21,8 +21,8 @@ zipkin_config& zipkin_config::get() { return the_one; } -void zipkin_config::init( const std::string& url, const std::string& service_name, uint32_t timeout_us ) { - get().zip = std::make_unique( url, service_name, timeout_us ); +void zipkin_config::init( const std::string& url, const std::string& service_name, uint32_t timeout_us, uint32_t retry_interval_us ) { + get().zip = std::make_unique( url, service_name, timeout_us, retry_interval_us ); } zipkin& zipkin_config::get_zipkin() { @@ -57,6 +57,7 @@ class zipkin::impl { const std::string zipkin_url; const std::string service_name; const uint32_t timeout_us; + const uint32_t retry_interval_us; std::mutex mtx; uint64_t next_id = 0; http_client http; @@ -72,10 +73,11 @@ class zipkin::impl { boost::asio::io_context::strand work_strand{ctx}; boost::asio::executor_work_guard work_guard = boost::asio::make_work_guard(ctx); - impl( std::string url, std::string service_name, uint32_t timeout_us ) + impl( std::string url, std::string service_name, uint32_t timeout_us, uint32_t retry_interval_us ) : zipkin_url( std::move(url) ) , service_name( std::move(service_name) ) - , timeout_us( timeout_us ) { + , timeout_us( timeout_us ) + , retry_interval_us( retry_interval_us ) { } void init(); @@ -110,8 +112,8 @@ void zipkin::impl::shutdown() { thread.join(); } -zipkin::zipkin( const std::string& url, const std::string& service_name, uint32_t timeout_us ) : - my( new impl( url, service_name, timeout_us ) ) { +zipkin::zipkin( const std::string& url, const std::string& service_name, uint32_t timeout_us, uint32_t retry_interval_us ) : + my( new impl( url, service_name, timeout_us, retry_interval_us ) ) { my->init(); } @@ -185,7 +187,7 @@ void zipkin::log( zipkin_span::span_data&& span ) { if( my->consecutive_errors > 0 ) { if( my->timer_expired ) { my->timer_expired = false; - my->timer.expires_from_now(boost::posix_time::seconds(30)); + my->timer.expires_from_now(boost::posix_time::microsec(my->retry_interval_us)); my->timer.async_wait([this, span{std::move(span)}](auto&) mutable { ilog("Retry connecting to zipkin: ${u} ...", ("u", my->zipkin_url) ); post_request(std::move(span)); From d740af36f7863358a34d356d35dffe46ca378462 Mon Sep 17 00:00:00 2001 From: Jingjun Zhao Date: Tue, 29 Jun 2021 16:13:08 -0400 Subject: [PATCH 108/124] Fix new comments --- include/fc/log/zipkin.hpp | 3 ++- src/log/zipkin.cpp | 18 ++++++++++-------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/include/fc/log/zipkin.hpp b/include/fc/log/zipkin.hpp index 052c0bfe0..2017c552b 100644 --- a/include/fc/log/zipkin.hpp +++ b/include/fc/log/zipkin.hpp @@ -31,7 +31,8 @@ class zipkin_config { /// Not thread safe, call from main thread before spawning any threads that might use zipkin. /// @param url the url endpoint of zipkin server. e.g. http://127.0.0.1:9411/api/v2/spans /// @param service_name the service name to include in each zipkin span - /// @param timeout_us the timeout in microseconds for each http call (9 consecutive failures and zipkin is disabled) + /// @param timeout_us the timeout in microseconds for each http call + /// (9 consecutive failures and zipkin is disabled, SIGHUP will reset the failure counter and re-enable zipkin) /// @param retry_interval_us the interval in microseconds for connecting to zipkin static void init( const std::string& url, const std::string& service_name, uint32_t timeout_us, uint32_t retry_interval_us ); diff --git a/src/log/zipkin.cpp b/src/log/zipkin.cpp index 5506f6595..4deb9ac9c 100644 --- a/src/log/zipkin.cpp +++ b/src/log/zipkin.cpp @@ -12,9 +12,11 @@ #include #include -namespace fc { +namespace { + std::atomic sighup_requested = false; +} -std::atomic sighup_requested = false; +namespace fc { zipkin_config& zipkin_config::get() { static zipkin_config the_one; @@ -47,7 +49,7 @@ uint64_t zipkin_config::get_next_unique_id() { void zipkin_config::handle_sighup(){ static_assert(std::atomic::is_always_lock_free == true, "expected a lock-free atomic type"); - fc::sighup_requested = true; + sighup_requested = true; } class zipkin::impl { @@ -177,9 +179,10 @@ void zipkin::post_request(zipkin_span::span_data&& span) { void zipkin::log( zipkin_span::span_data&& span ) { if( my->stopped ) { return; - }else if( fc::sighup_requested.load()) { - fc::sighup_requested = false; + }else if( sighup_requested.load()) { + sighup_requested = false; my->consecutive_errors = 0; + ilog("Retry connecting to zipkin: ${u} ...", ("u", my->zipkin_url) ); }else if( my->consecutive_errors > my->max_consecutive_errors ) { return; } @@ -188,9 +191,8 @@ void zipkin::log( zipkin_span::span_data&& span ) { if( my->timer_expired ) { my->timer_expired = false; my->timer.expires_from_now(boost::posix_time::microsec(my->retry_interval_us)); - my->timer.async_wait([this, span{std::move(span)}](auto&) mutable { - ilog("Retry connecting to zipkin: ${u} ...", ("u", my->zipkin_url) ); - post_request(std::move(span)); + my->timer.async_wait([this](auto&) mutable { + sighup_requested = true; my->timer_expired = true; }); } From 0b13fab1b7e18b1936789ebf4ccf6e4091123ffa Mon Sep 17 00:00:00 2001 From: Matt Witherspoon <32485495+spoonincode@users.noreply.github.com> Date: Sat, 10 Jul 2021 14:28:37 -0400 Subject: [PATCH 109/124] add includes needed for boost 1.77 --- include/fc/crypto/sha256.hpp | 2 ++ include/fc/io/raw.hpp | 1 + 2 files changed, 3 insertions(+) diff --git a/include/fc/crypto/sha256.hpp b/include/fc/crypto/sha256.hpp index 591a2fa38..96c6796b0 100644 --- a/include/fc/crypto/sha256.hpp +++ b/include/fc/crypto/sha256.hpp @@ -4,6 +4,8 @@ #include #include +#include + namespace fc { diff --git a/include/fc/io/raw.hpp b/include/fc/io/raw.hpp index afab435bc..62fb508b4 100644 --- a/include/fc/io/raw.hpp +++ b/include/fc/io/raw.hpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include From cb479005d34490cbe7a473a80b44a321152157d0 Mon Sep 17 00:00:00 2001 From: Matt Witherspoon <32485495+spoonincode@users.noreply.github.com> Date: Sat, 10 Jul 2021 14:28:37 -0400 Subject: [PATCH 110/124] add includes needed for boost 1.77 --- include/fc/crypto/sha256.hpp | 2 ++ include/fc/io/raw.hpp | 1 + 2 files changed, 3 insertions(+) diff --git a/include/fc/crypto/sha256.hpp b/include/fc/crypto/sha256.hpp index 591a2fa38..96c6796b0 100644 --- a/include/fc/crypto/sha256.hpp +++ b/include/fc/crypto/sha256.hpp @@ -4,6 +4,8 @@ #include #include +#include + namespace fc { diff --git a/include/fc/io/raw.hpp b/include/fc/io/raw.hpp index afab435bc..62fb508b4 100644 --- a/include/fc/io/raw.hpp +++ b/include/fc/io/raw.hpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include From 9a99032f027a62de0eeca5c2ccda8faebc24fa9f Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Tue, 20 Jul 2021 11:01:42 -0500 Subject: [PATCH 111/124] Cancel timer and don't access my when shutdown to fix core-dump --- src/log/zipkin.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/log/zipkin.cpp b/src/log/zipkin.cpp index 4deb9ac9c..ae803ff65 100644 --- a/src/log/zipkin.cpp +++ b/src/log/zipkin.cpp @@ -110,6 +110,8 @@ zipkin::impl::~impl() { void zipkin::impl::shutdown() { if( stopped ^= 1 ) return; + boost::system::error_code ec; + timer.cancel(ec); work_guard.reset(); // drain the queue thread.join(); } @@ -191,9 +193,10 @@ void zipkin::log( zipkin_span::span_data&& span ) { if( my->timer_expired ) { my->timer_expired = false; my->timer.expires_from_now(boost::posix_time::microsec(my->retry_interval_us)); - my->timer.async_wait([this](auto&) mutable { + my->timer.async_wait([this](const boost::system::error_code& ec) mutable { sighup_requested = true; - my->timer_expired = true; + if(!ec) + my->timer_expired = true; }); } }else { From 2cf87d1c3aaade7224330e46435d12e12443e7f5 Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Tue, 20 Jul 2021 11:07:21 -0500 Subject: [PATCH 112/124] Remove unneeded mutable --- src/log/zipkin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/log/zipkin.cpp b/src/log/zipkin.cpp index ae803ff65..5632f32a8 100644 --- a/src/log/zipkin.cpp +++ b/src/log/zipkin.cpp @@ -193,7 +193,7 @@ void zipkin::log( zipkin_span::span_data&& span ) { if( my->timer_expired ) { my->timer_expired = false; my->timer.expires_from_now(boost::posix_time::microsec(my->retry_interval_us)); - my->timer.async_wait([this](const boost::system::error_code& ec) mutable { + my->timer.async_wait([this](const boost::system::error_code& ec) { sighup_requested = true; if(!ec) my->timer_expired = true; From 0e0fe0c0f49fd41cbc00c3bcf37051fa31a871ae Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Tue, 20 Jul 2021 11:01:42 -0500 Subject: [PATCH 113/124] Cancel timer and don't access my when shutdown to fix core-dump --- src/log/zipkin.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/log/zipkin.cpp b/src/log/zipkin.cpp index 4deb9ac9c..ae803ff65 100644 --- a/src/log/zipkin.cpp +++ b/src/log/zipkin.cpp @@ -110,6 +110,8 @@ zipkin::impl::~impl() { void zipkin::impl::shutdown() { if( stopped ^= 1 ) return; + boost::system::error_code ec; + timer.cancel(ec); work_guard.reset(); // drain the queue thread.join(); } @@ -191,9 +193,10 @@ void zipkin::log( zipkin_span::span_data&& span ) { if( my->timer_expired ) { my->timer_expired = false; my->timer.expires_from_now(boost::posix_time::microsec(my->retry_interval_us)); - my->timer.async_wait([this](auto&) mutable { + my->timer.async_wait([this](const boost::system::error_code& ec) mutable { sighup_requested = true; - my->timer_expired = true; + if(!ec) + my->timer_expired = true; }); } }else { From 2889bbde782a5bac96ee414fbeac73d027a4f063 Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Tue, 20 Jul 2021 11:07:21 -0500 Subject: [PATCH 114/124] Remove unneeded mutable --- src/log/zipkin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/log/zipkin.cpp b/src/log/zipkin.cpp index ae803ff65..5632f32a8 100644 --- a/src/log/zipkin.cpp +++ b/src/log/zipkin.cpp @@ -193,7 +193,7 @@ void zipkin::log( zipkin_span::span_data&& span ) { if( my->timer_expired ) { my->timer_expired = false; my->timer.expires_from_now(boost::posix_time::microsec(my->retry_interval_us)); - my->timer.async_wait([this](const boost::system::error_code& ec) mutable { + my->timer.async_wait([this](const boost::system::error_code& ec) { sighup_requested = true; if(!ec) my->timer_expired = true; From 6387b46c7488cddfdeefd3ec27bca6b7f81f9959 Mon Sep 17 00:00:00 2001 From: Huang-Ming Huang Date: Sun, 9 May 2021 15:23:49 -0500 Subject: [PATCH 115/124] implement zipkin nested span fix fc_create_trace change macro to inline functions add debug message add create_trace_with_start_time use lagacy format for zipkin add fc_trace_log address PR comments add zipkin wait mechanism address PR comments fix indent fix compile problem # Conflicts: # src/network/http/http_client.cpp add fc_create_trace_with_id_if() --- include/fc/log/trace.hpp | 103 ++++++++++++++++------- include/fc/log/zipkin.hpp | 68 +++++++-------- include/fc/network/http/http_client.hpp | 23 +++-- src/log/zipkin.cpp | 106 ++++++++++++++++++++---- src/network/http/http_client.cpp | 18 ++-- 5 files changed, 217 insertions(+), 101 deletions(-) diff --git a/include/fc/log/trace.hpp b/include/fc/log/trace.hpp index 6a0d3de14..5d9e62b98 100644 --- a/include/fc/log/trace.hpp +++ b/include/fc/log/trace.hpp @@ -1,44 +1,85 @@ #pragma once #include +#include #include -/// @param TRACE_STR const char* identifier for trace +/// @param trace_str const char* identifier for trace /// @return implementation defined type RAII object that submits trace on exit of scope -#define fc_create_trace( TRACE_STR ) \ - ::fc::zipkin_config::is_enabled() ? \ - ::fc::optional_trace{ ::std::optional<::fc::zipkin_trace>( ::std::in_place, (TRACE_STR) ) } \ - : ::fc::optional_trace{}; +inline ::std::optional<::fc::zipkin_span> fc_create_trace(const char* trace_str) { + return ::fc::zipkin_config::is_enabled() + ? ::std::optional<::fc::zipkin_span>(::std::in_place, ::fc::zipkin_config::get_next_unique_id(), + (trace_str), 0, 0) + : ::std::optional<::fc::zipkin_span>{}; +} -/// @param TRACE_STR const char* identifier for trace -/// @param TRACE_ID fc::sha256 id to use +/// @param trace_str const char* identifier for trace +/// @param trace_id fc::sha256 id to use /// @return implementation defined type RAII object that submits trace on exit of scope -#define fc_create_trace_with_id( TRACE_STR, TRACE_ID ) \ - ::fc::zipkin_config::is_enabled() ? \ - ::fc::optional_trace{ ::std::optional<::fc::zipkin_trace>( ::std::in_place, ::fc::zipkin_span::to_id(TRACE_ID), (TRACE_STR) ) } \ - : ::fc::optional_trace{}; +inline ::std::optional<::fc::zipkin_span> fc_create_trace_with_id(const char* trace_str, const fc::sha256& trace_id) { + return ::fc::zipkin_config::is_enabled() + ? ::std::optional<::fc::zipkin_span>(::std::in_place, ::fc::zipkin_span::to_id(trace_id), (trace_str), 0 , 0) + : ::std::optional<::fc::zipkin_span>{}; +} -/// @param TRACE_VARNAME variable returned from fc_create_trace -/// @param SPAN_STR const char* indentifier +/// @param condition create the trace only when the condition is true +/// @param trace_str const char* identifier for trace +/// @param trace_id fc::sha256 id to use +/// @return implementation defined type RAII object that submits trace on exit of scope +inline ::std::optional<::fc::zipkin_span> fc_create_trace_with_id_if(bool condition, const char* trace_str, const fc::sha256& trace_id) { + return (condition && ::fc::zipkin_config::is_enabled()) + ? ::std::optional<::fc::zipkin_span>(::std::in_place, ::fc::zipkin_span::to_id(trace_id), (trace_str), ::fc::zipkin_span::to_id(trace_id) , 0) + : ::std::optional<::fc::zipkin_span>{}; +} + +inline ::std::optional<::fc::zipkin_span> fc_create_span_with_id(const char* span_str, uint64_t id, const fc::sha256& trace_id) { + auto tid = ::fc::zipkin_span::to_id(trace_id); + return ::fc::zipkin_config::is_enabled() + ? ::std::optional<::fc::zipkin_span>(::std::in_place, id, span_str, tid, tid) + : ::std::optional<::fc::zipkin_span>{}; +} + +inline ::std::optional<::fc::zipkin_span> fc_create_trace_with_start_time(const char* trace_str, fc::time_point start) { + return ::fc::zipkin_config::is_enabled() + ? ::std::optional<::fc::zipkin_span>(::std::in_place, trace_str, start) + : ::std::optional<::fc::zipkin_span>{}; +} + +/// @param trace variable returned from fc_create_trace +/// @param span_str const char* indentifier /// @return implementation defined type RAII object that submits span on exit of scope -#define fc_create_span( TRACE_VARNAME, SPAN_STR ) \ - ( (TRACE_VARNAME) && ::fc::zipkin_config::is_enabled() ) ? \ - (TRACE_VARNAME).opt->create_span( (SPAN_STR) ) \ - : ::std::optional<::fc::zipkin_span>{}; +inline ::std::optional<::fc::zipkin_span> fc_create_span(const ::std::optional<::fc::zipkin_span>& trace, + const char* span_str) { + return ((trace) && ::fc::zipkin_config::is_enabled()) ? (trace)->create_span((span_str)) + : ::std::optional<::fc::zipkin_span>{}; +} -/// @param TRACE_TOKEN variable returned from trace.get_token() -/// @param SPAN_STR const char* indentifier +/// @param trace_token variable returned from trace.get_token() +/// @param span_str const char* indentifier /// @return implementation defined type RAII object that submits span on exit of scope -#define fc_create_span_from_token( TRACE_TOKEN, SPAN_STR ) \ - ( (TRACE_TOKEN) && ::fc::zipkin_config::is_enabled() ) ? \ - ::fc::zipkin_trace::create_span_from_token( (TRACE_TOKEN), (SPAN_STR) ) \ - : ::std::optional<::fc::zipkin_span>{}; - -/// @param SPAN_VARNAME variable returned from fc_create_span -/// @param TAG_KEY_STR string key -/// @param TAG_VALUE string value -#define fc_add_tag( SPAN_VARNAME, TAG_KEY_STR, TAG_VALUE_STR) \ +inline ::std::optional<::fc::zipkin_span> fc_create_span_from_token(fc::zipkin_span::token trace_token, + const char* span_str) { + return ((trace_token) && ::fc::zipkin_config::is_enabled()) + ? ::fc::zipkin_span::create_span_from_token((trace_token), (span_str)) + : ::std::optional<::fc::zipkin_span>{}; +} + +/// @param span variable returned from fc_create_span +/// @param tag_key_str string key +/// @param tag_value string value +template +inline void fc_add_tag(::std::optional<::fc::zipkin_span>& span, const char* tag_key_str, Value&& value) { + if ((span) && ::fc::zipkin_config::is_enabled()) + (span)->add_tag((tag_key_str), std::forward(value)); +} + +inline fc::zipkin_span::token fc_get_token(const ::std::optional<::fc::zipkin_span>& span) { + return (span && ::fc::zipkin_config::is_enabled()) ? span->get_token() : fc::zipkin_span::token(0, 0); +} + + +#define fc_trace_log( TRACE_OR_SPAN, FORMAT, ... ) \ FC_MULTILINE_MACRO_BEGIN \ - if( (SPAN_VARNAME) && ::fc::zipkin_config::is_enabled() ) \ - (SPAN_VARNAME)->add_tag( (TAG_KEY_STR), (TAG_VALUE_STR) ); \ - FC_MULTILINE_MACRO_END + if( (fc::logger::get(DEFAULT_LOGGER)).is_enabled( fc::log_level::info ) ) \ + (fc::logger::get(DEFAULT_LOGGER)).log( FC_LOG_MESSAGE( info, FORMAT " traceID=${_the_trace_id_}", ("_the_trace_id_", TRACE_OR_SPAN->trace_id_string()) __VA_ARGS__ ) ); \ + FC_MULTILINE_MACRO_END \ No newline at end of file diff --git a/include/fc/log/zipkin.hpp b/include/fc/log/zipkin.hpp index 2017c552b..3af878547 100644 --- a/include/fc/log/zipkin.hpp +++ b/include/fc/log/zipkin.hpp @@ -34,7 +34,8 @@ class zipkin_config { /// @param timeout_us the timeout in microseconds for each http call /// (9 consecutive failures and zipkin is disabled, SIGHUP will reset the failure counter and re-enable zipkin) /// @param retry_interval_us the interval in microseconds for connecting to zipkin - static void init( const std::string& url, const std::string& service_name, uint32_t timeout_us, uint32_t retry_interval_us ); + /// @param wait_time_seconds the initial wait time in seconds for connecting to zipkin, an exception is thrown when the connection is not established within the wait time. + static void init( const std::string& url, const std::string& service_name, uint32_t timeout_us, uint32_t retry_interval_us, uint32_t wait_time_seconds = 0 ); /// Thread safe only if init() called from main thread before spawning of any threads /// @throw assert_exception if called before init() @@ -63,11 +64,14 @@ class zipkin_config { }; struct zipkin_span { - explicit zipkin_span( std::string name, uint64_t parent_id = 0 ) - : data( std::move( name ), parent_id ) {} + explicit zipkin_span( std::string name, uint64_t trace_id, uint64_t parent_id ) + : data( std::move( name ), trace_id, parent_id ) {} - explicit zipkin_span( uint64_t id, std::string name, uint64_t parent_id = 0 ) - : data( id, std::move( name ), parent_id ) {} + explicit zipkin_span( uint64_t id, std::string name, uint64_t trace_id, uint64_t parent_id ) + : data( id, std::move( name ), trace_id, parent_id ) {} + + explicit zipkin_span( std::string name, fc::time_point start ) + : data( std::move( name ), start ) {} zipkin_span( const zipkin_span& ) = delete; zipkin_span& operator=( const zipkin_span& ) = delete; @@ -112,29 +116,28 @@ struct zipkin_span { friend struct zipkin_trace; friend struct optional_trace; constexpr explicit operator bool() const noexcept { return id != 0; } + token( uint64_t id, uint64_t trace_id ) + : id( id ), trace_id( trace_id ) {} private: - explicit token( uint64_t id ) - : id( id ) {} uint64_t id; + uint64_t trace_id; }; - token get_token() const { return token{data.id}; }; + token get_token() const { return token{data.id, data.trace_id }; }; static uint64_t to_id( const fc::sha256& id ); - template - static uint64_t to_id( const T& id ) { - static_assert( std::is_same_v, "expected uint64_t" ); - return id.data()[3]; - } - struct span_data { - explicit span_data( std::string name, uint64_t parent_id = 0 ) - : id( zipkin_config::get_next_unique_id() ), parent_id( parent_id ), + explicit span_data( std::string name, uint64_t trace_id, uint64_t parent_id ) + : id( zipkin_config::get_next_unique_id() ), trace_id( trace_id ), parent_id( parent_id ), start( time_point::now() ), name( std::move( name ) ) {} - explicit span_data( uint64_t id, std::string name, uint64_t parent_id = 0 ) - : id( id ), parent_id( parent_id ), start( time_point::now() ), name( std::move( name ) ) {} + explicit span_data( uint64_t id, std::string name, uint64_t trace_id, uint64_t parent_id ) + : id( id ), trace_id( trace_id == 0 ? id : trace_id ), parent_id( parent_id ), start( time_point::now() ), name( std::move( name ) ) {} + + explicit span_data( std::string name, fc::time_point start) + : id( zipkin_config::get_next_unique_id() ), trace_id( zipkin_config::get_next_unique_id() ), parent_id( 0 ), + start( start), name( std::move( name ) ) {} span_data( const span_data& ) = delete; span_data& operator=( const span_data& ) = delete; @@ -142,44 +145,31 @@ struct zipkin_span { span_data( span_data&& rhs ) = default; uint64_t id; - // zipkin traceId and parentId are same (when parent_id set) since only allowing trace with span children. - // Not currently supporting spans with children, only trace with children spans. - const uint64_t parent_id; - const fc::time_point start; + const uint64_t trace_id; + const uint64_t parent_id; + const fc::time_point start; fc::time_point stop; std::string name; fc::mutable_variant_object tags; }; - span_data data; -}; - -struct zipkin_trace : public zipkin_span { - using zipkin_span::zipkin_span; - [[nodiscard]] std::optional create_span( std::string name ) const { - return zipkin_span{std::move( name ), get_token().id}; + return create_span_from_token(get_token(), std::move(name)); } [[nodiscard]] static std::optional create_span_from_token( zipkin_span::token token, std::string name ) { - return zipkin_span{std::move( name ), token.id}; + return zipkin_span{std::move( name ), token.trace_id, token.id}; } -}; -struct optional_trace { - std::optional opt; + std::string trace_id_string() const; - constexpr explicit operator bool() const noexcept { return opt.has_value(); } - - [[nodiscard]] zipkin_span::token get_token() const { - return opt ? opt->get_token() : zipkin_span::token( 0 ); - } + span_data data; }; class zipkin { public: - zipkin( const std::string& url, const std::string& service_name, uint32_t timeout_us, uint32_t retry_interval_us ); + zipkin( const std::string& url, const std::string& service_name, uint32_t timeout_us, uint32_t retry_interval_us , uint32_t wait_time_seconds ); /// finishes logging all queued up spans ~zipkin() = default; diff --git a/include/fc/network/http/http_client.hpp b/include/fc/network/http/http_client.hpp index 47a38f434..84dd5891d 100644 --- a/include/fc/network/http/http_client.hpp +++ b/include/fc/network/http/http_client.hpp @@ -9,6 +9,7 @@ #include #include #include +#include namespace fc { @@ -17,13 +18,21 @@ class http_client { http_client(); ~http_client(); - variant post_sync(const url& dest, const variant& payload, const time_point& deadline = time_point::maximum()); - - template - variant post_sync(const url& dest, const T& payload, const time_point& deadline = time_point::maximum()) { - variant payload_v; - to_variant(payload, payload_v); - return post_sync(dest, payload_v, deadline); + variant + post_sync(const url &dest, const variant &payload, + const time_point &deadline = time_point::maximum(), + json::output_formatting formatting = + json::output_formatting::stringify_large_ints_and_doubles); + + template + variant + post_sync(const url &dest, const T &payload, + const time_point &deadline = time_point::maximum(), + json::output_formatting formatting = + json::output_formatting::stringify_large_ints_and_doubles) { + variant payload_v; + to_variant(payload, payload_v); + return post_sync(dest, payload_v, deadline, formatting); } void add_cert(const std::string& cert_pem_string); diff --git a/src/log/zipkin.cpp b/src/log/zipkin.cpp index 5632f32a8..c45ca1ea4 100644 --- a/src/log/zipkin.cpp +++ b/src/log/zipkin.cpp @@ -18,13 +18,56 @@ namespace { namespace fc { +struct local_endpoint_resolver { + using tcp = boost::asio::ip::tcp; + using error_code = boost::system::error_code; + + local_endpoint_resolver() + : resolver(ctx) + , sock(ctx) + , timer(ctx) {} + boost::asio::io_context ctx; + tcp::resolver resolver; + tcp::socket sock; + boost::asio::deadline_timer timer; + std::string remote; + tcp::resolver::results_type endpoints; + std::optional local_endpoint; + + void async_resolve(std::string remote_host, std::string port) { + remote = remote_host + ":" + port; + resolver.async_resolve(remote_host, port, [this](const error_code& ec, tcp::resolver::results_type resolved) { + if (ec) + throw boost::system::system_error(ec); + endpoints = resolved; + do_connect(); + }); + } + + void do_connect() { + boost::asio::async_connect(sock, endpoints, [this](const error_code& ec, const tcp::endpoint& endpoint) { + if (ec) { + wlog("failed to connect to ${remote}, retry in 5 seconds", ("remote", remote)); + timer.expires_from_now(boost::posix_time::seconds(5)); + timer.async_wait([this](const error_code& ec) { + if (!ec) + do_connect(); + }); + return; + } + local_endpoint = sock.local_endpoint(); + ilog("connected to ${remote}", ("remote", remote)); + }); + } +}; + zipkin_config& zipkin_config::get() { static zipkin_config the_one; return the_one; } -void zipkin_config::init( const std::string& url, const std::string& service_name, uint32_t timeout_us, uint32_t retry_interval_us ) { - get().zip = std::make_unique( url, service_name, timeout_us, retry_interval_us ); +void zipkin_config::init( const std::string& url, const std::string& service_name, uint32_t timeout_us, uint32_t retry_interval_us, uint32_t wait_time_seconds ) { + get().zip = std::make_unique( url, service_name, timeout_us, retry_interval_us, wait_time_seconds ); } zipkin& zipkin_config::get_zipkin() { @@ -74,6 +117,8 @@ class zipkin::impl { boost::asio::deadline_timer timer{ctx}; boost::asio::io_context::strand work_strand{ctx}; boost::asio::executor_work_guard work_guard = boost::asio::make_work_guard(ctx); + std::optional local_endpoint; + impl( std::string url, std::string service_name, uint32_t timeout_us, uint32_t retry_interval_us ) : zipkin_url( std::move(url) ) @@ -82,7 +127,7 @@ class zipkin::impl { , retry_interval_us( retry_interval_us ) { } - void init(); + void init(uint32_t wait_time_seconds); void shutdown(); void log( zipkin_span::span_data&& span ); @@ -90,7 +135,24 @@ class zipkin::impl { ~impl(); }; -void zipkin::impl::init() { +void zipkin::impl::init(uint32_t wait_time_seconds) { + if (wait_time_seconds > 0) { + endpoint = url( zipkin_url ); + if (!endpoint->host() || endpoint->host()->empty()) + FC_THROW("Invalid url ${url}", ("url", zipkin_url)); + + local_endpoint_resolver resolver; + resolver.async_resolve(*endpoint->host(), std::to_string(*endpoint->port())); + auto deadline = std::chrono::system_clock::now() + std::chrono::seconds(wait_time_seconds); + resolver.ctx.run_until(deadline); + + local_endpoint = resolver.local_endpoint; + + if (!local_endpoint) { + FC_THROW("Unable to connect to ${url} within ${wait_time_seconds} seconds", ("url", zipkin_url)("wait_time_seconds", wait_time_seconds)); + } + } + thread = std::thread( [this]() { fc::set_os_thread_name( "zipkin" ); while( true ) { @@ -116,9 +178,9 @@ void zipkin::impl::shutdown() { thread.join(); } -zipkin::zipkin( const std::string& url, const std::string& service_name, uint32_t timeout_us, uint32_t retry_interval_us ) : +zipkin::zipkin( const std::string& url, const std::string& service_name, uint32_t timeout_us, uint32_t retry_interval_us, uint32_t wait_time_seconds ) : my( new impl( url, service_name, timeout_us, retry_interval_us ) ) { - my->init(); + my->init(wait_time_seconds); } uint64_t zipkin::get_next_unique_id() { @@ -135,7 +197,7 @@ void zipkin::shutdown() { my->shutdown(); } -fc::variant create_zipkin_variant( zipkin_span::span_data&& span, const std::string& service_name ) { +fc::variant create_zipkin_variant( zipkin_span::span_data&& span, const std::string& service_name, std::optional& local_endpoint ) { // https://zipkin.io/zipkin-api/ // std::string traceId; // [a-f0-9]{16,32} unique id for trace, all children spans shared same id // std::string name; // logical operation, should have low cardinality @@ -144,23 +206,22 @@ fc::variant create_zipkin_variant( zipkin_span::span_data&& span, const std::str // int64_t timestamp // epoch microseconds of start of span // int64_t duration // microseconds of span - uint64_t trace_id; - if( span.parent_id != 0 ) { - trace_id = span.parent_id; - } else { - trace_id = span.id; - } - fc::mutable_variant_object mvo; mvo( "id", fc::to_hex( reinterpret_cast(&span.id), sizeof( span.id ) ) ); - mvo( "traceId", fc::to_hex( reinterpret_cast(&trace_id), sizeof( trace_id ) ) ); + mvo( "traceId", fc::to_hex( reinterpret_cast(&span.trace_id), sizeof( span.trace_id ) ) ); if( span.parent_id != 0 ) { mvo( "parentId", fc::to_hex( reinterpret_cast(&span.parent_id), sizeof( span.parent_id ) ) ); } mvo( "name", std::move( span.name ) ); mvo( "timestamp", span.start.time_since_epoch().count() ); mvo( "duration", (span.stop - span.start).count() ); - mvo( "localEndpoint", fc::variant_object( "serviceName", service_name ) ); + + mutable_variant_object local_endpoint_mvo("serviceName", service_name); + if (local_endpoint) { + const auto &address = local_endpoint->address(); + local_endpoint_mvo( address.is_v4() ? "ipv4": "ipv6", address.to_string()); + } + mvo( "localEndpoint", local_endpoint_mvo ); mvo( "tags", std::move( span.tags ) ); span.id = 0; // stop destructor of span from calling log again @@ -205,8 +266,13 @@ void zipkin::log( zipkin_span::span_data&& span ) { } void zipkin::impl::log( zipkin_span::span_data&& span ) { - if( consecutive_errors > max_consecutive_errors ) + if (consecutive_errors > max_consecutive_errors) { + wlog("consecutive_errors=${consecutive_errors} exceeds " + "limit($max_consecutive_errors)", + ("consecutive_errors", consecutive_errors.load())("max_consecutive_errors", + max_consecutive_errors)); return; + } try { auto deadline = fc::time_point::now() + fc::microseconds( timeout_us ); @@ -215,7 +281,7 @@ void zipkin::impl::log( zipkin_span::span_data&& span ) { dlog( "connecting to zipkin: ${p}", ("p", *endpoint) ); } - http.post_sync( *endpoint, create_zipkin_variant( std::move( span ), service_name ), deadline ); + http.post_sync(*endpoint, create_zipkin_variant(std::move(span), service_name, local_endpoint), deadline, fc::json::output_formatting::legacy_generator); consecutive_errors = 0; if (!connected){ @@ -250,4 +316,8 @@ zipkin_span::~zipkin_span() { } catch( ... ) {} } +std::string zipkin_span::trace_id_string() const { + return fc::to_hex(reinterpret_cast(&data.trace_id), sizeof(data.trace_id)); +} + } // fc diff --git a/src/network/http/http_client.cpp b/src/network/http/http_client.cpp index 34adb7b41..8d712a44e 100644 --- a/src/network/http/http_client.cpp +++ b/src/network/http/http_client.cpp @@ -300,7 +300,10 @@ class http_client_impl { const deadline_type& deadline; }; - variant post_sync(const url& dest, const variant& payload, const fc::time_point& _deadline) { + variant + post_sync(const url &dest, const variant &payload, + const fc::time_point &_deadline, + json::output_formatting formatting) { static const deadline_type epoch(boost::gregorian::date(1970, 1, 1)); auto deadline = epoch + boost::posix_time::microseconds(_deadline.time_since_epoch().count()); FC_ASSERT(dest.host(), "No host set on URL"); @@ -324,7 +327,7 @@ class http_client_impl { req.set(http::field::user_agent, BOOST_BEAST_VERSION_STRING); req.set(http::field::content_type, "application/json"); req.keep_alive(true); - req.body() = json::to_string(payload, _deadline); + req.body() = json::to_string(payload, _deadline, formatting); req.prepare_payload(); auto conn_iter = get_connection(dest, deadline); @@ -379,6 +382,8 @@ class http_client_impl { } } else if (res.result() == http::status::not_found) { FC_THROW("URL not found: ${url}", ("url", (std::string)dest)); + } else if (res.result() == http::status::bad_request) { + FC_THROW("Received request: ${msg}", ("msg", res.body())); } return result; @@ -432,11 +437,12 @@ http_client::http_client() } -variant http_client::post_sync(const url& dest, const variant& payload, const fc::time_point& deadline) { - if(dest.proto() == "unix") - return _my->post_sync(_my->get_unix_url(*dest.host()), payload, deadline); +variant http_client::post_sync(const url& dest, const variant& payload, const fc::time_point& deadline, + json::output_formatting formatting) { + if (dest.proto() == "unix") + return _my->post_sync(_my->get_unix_url(*dest.host()), payload, deadline, formatting); else - return _my->post_sync(dest, payload, deadline); + return _my->post_sync(dest, payload, deadline, formatting); } void http_client::add_cert(const std::string& cert_pem_string) { From 138da8c8f97a128f7455e3055679ad26c0d0d333 Mon Sep 17 00:00:00 2001 From: Huang-Ming Huang Date: Sun, 9 May 2021 15:23:49 -0500 Subject: [PATCH 116/124] implement zipkin nested span fix fc_create_trace change macro to inline functions add debug message add create_trace_with_start_time use lagacy format for zipkin add fc_trace_log address PR comments add zipkin wait mechanism address PR comments fix indent fix compile problem # Conflicts: # src/network/http/http_client.cpp add fc_create_trace_with_id_if() --- include/fc/log/trace.hpp | 103 ++++++++++++++++------- include/fc/log/zipkin.hpp | 68 +++++++-------- include/fc/network/http/http_client.hpp | 23 +++-- src/log/zipkin.cpp | 106 ++++++++++++++++++++---- src/network/http/http_client.cpp | 18 ++-- 5 files changed, 217 insertions(+), 101 deletions(-) diff --git a/include/fc/log/trace.hpp b/include/fc/log/trace.hpp index 6a0d3de14..5d9e62b98 100644 --- a/include/fc/log/trace.hpp +++ b/include/fc/log/trace.hpp @@ -1,44 +1,85 @@ #pragma once #include +#include #include -/// @param TRACE_STR const char* identifier for trace +/// @param trace_str const char* identifier for trace /// @return implementation defined type RAII object that submits trace on exit of scope -#define fc_create_trace( TRACE_STR ) \ - ::fc::zipkin_config::is_enabled() ? \ - ::fc::optional_trace{ ::std::optional<::fc::zipkin_trace>( ::std::in_place, (TRACE_STR) ) } \ - : ::fc::optional_trace{}; +inline ::std::optional<::fc::zipkin_span> fc_create_trace(const char* trace_str) { + return ::fc::zipkin_config::is_enabled() + ? ::std::optional<::fc::zipkin_span>(::std::in_place, ::fc::zipkin_config::get_next_unique_id(), + (trace_str), 0, 0) + : ::std::optional<::fc::zipkin_span>{}; +} -/// @param TRACE_STR const char* identifier for trace -/// @param TRACE_ID fc::sha256 id to use +/// @param trace_str const char* identifier for trace +/// @param trace_id fc::sha256 id to use /// @return implementation defined type RAII object that submits trace on exit of scope -#define fc_create_trace_with_id( TRACE_STR, TRACE_ID ) \ - ::fc::zipkin_config::is_enabled() ? \ - ::fc::optional_trace{ ::std::optional<::fc::zipkin_trace>( ::std::in_place, ::fc::zipkin_span::to_id(TRACE_ID), (TRACE_STR) ) } \ - : ::fc::optional_trace{}; +inline ::std::optional<::fc::zipkin_span> fc_create_trace_with_id(const char* trace_str, const fc::sha256& trace_id) { + return ::fc::zipkin_config::is_enabled() + ? ::std::optional<::fc::zipkin_span>(::std::in_place, ::fc::zipkin_span::to_id(trace_id), (trace_str), 0 , 0) + : ::std::optional<::fc::zipkin_span>{}; +} -/// @param TRACE_VARNAME variable returned from fc_create_trace -/// @param SPAN_STR const char* indentifier +/// @param condition create the trace only when the condition is true +/// @param trace_str const char* identifier for trace +/// @param trace_id fc::sha256 id to use +/// @return implementation defined type RAII object that submits trace on exit of scope +inline ::std::optional<::fc::zipkin_span> fc_create_trace_with_id_if(bool condition, const char* trace_str, const fc::sha256& trace_id) { + return (condition && ::fc::zipkin_config::is_enabled()) + ? ::std::optional<::fc::zipkin_span>(::std::in_place, ::fc::zipkin_span::to_id(trace_id), (trace_str), ::fc::zipkin_span::to_id(trace_id) , 0) + : ::std::optional<::fc::zipkin_span>{}; +} + +inline ::std::optional<::fc::zipkin_span> fc_create_span_with_id(const char* span_str, uint64_t id, const fc::sha256& trace_id) { + auto tid = ::fc::zipkin_span::to_id(trace_id); + return ::fc::zipkin_config::is_enabled() + ? ::std::optional<::fc::zipkin_span>(::std::in_place, id, span_str, tid, tid) + : ::std::optional<::fc::zipkin_span>{}; +} + +inline ::std::optional<::fc::zipkin_span> fc_create_trace_with_start_time(const char* trace_str, fc::time_point start) { + return ::fc::zipkin_config::is_enabled() + ? ::std::optional<::fc::zipkin_span>(::std::in_place, trace_str, start) + : ::std::optional<::fc::zipkin_span>{}; +} + +/// @param trace variable returned from fc_create_trace +/// @param span_str const char* indentifier /// @return implementation defined type RAII object that submits span on exit of scope -#define fc_create_span( TRACE_VARNAME, SPAN_STR ) \ - ( (TRACE_VARNAME) && ::fc::zipkin_config::is_enabled() ) ? \ - (TRACE_VARNAME).opt->create_span( (SPAN_STR) ) \ - : ::std::optional<::fc::zipkin_span>{}; +inline ::std::optional<::fc::zipkin_span> fc_create_span(const ::std::optional<::fc::zipkin_span>& trace, + const char* span_str) { + return ((trace) && ::fc::zipkin_config::is_enabled()) ? (trace)->create_span((span_str)) + : ::std::optional<::fc::zipkin_span>{}; +} -/// @param TRACE_TOKEN variable returned from trace.get_token() -/// @param SPAN_STR const char* indentifier +/// @param trace_token variable returned from trace.get_token() +/// @param span_str const char* indentifier /// @return implementation defined type RAII object that submits span on exit of scope -#define fc_create_span_from_token( TRACE_TOKEN, SPAN_STR ) \ - ( (TRACE_TOKEN) && ::fc::zipkin_config::is_enabled() ) ? \ - ::fc::zipkin_trace::create_span_from_token( (TRACE_TOKEN), (SPAN_STR) ) \ - : ::std::optional<::fc::zipkin_span>{}; - -/// @param SPAN_VARNAME variable returned from fc_create_span -/// @param TAG_KEY_STR string key -/// @param TAG_VALUE string value -#define fc_add_tag( SPAN_VARNAME, TAG_KEY_STR, TAG_VALUE_STR) \ +inline ::std::optional<::fc::zipkin_span> fc_create_span_from_token(fc::zipkin_span::token trace_token, + const char* span_str) { + return ((trace_token) && ::fc::zipkin_config::is_enabled()) + ? ::fc::zipkin_span::create_span_from_token((trace_token), (span_str)) + : ::std::optional<::fc::zipkin_span>{}; +} + +/// @param span variable returned from fc_create_span +/// @param tag_key_str string key +/// @param tag_value string value +template +inline void fc_add_tag(::std::optional<::fc::zipkin_span>& span, const char* tag_key_str, Value&& value) { + if ((span) && ::fc::zipkin_config::is_enabled()) + (span)->add_tag((tag_key_str), std::forward(value)); +} + +inline fc::zipkin_span::token fc_get_token(const ::std::optional<::fc::zipkin_span>& span) { + return (span && ::fc::zipkin_config::is_enabled()) ? span->get_token() : fc::zipkin_span::token(0, 0); +} + + +#define fc_trace_log( TRACE_OR_SPAN, FORMAT, ... ) \ FC_MULTILINE_MACRO_BEGIN \ - if( (SPAN_VARNAME) && ::fc::zipkin_config::is_enabled() ) \ - (SPAN_VARNAME)->add_tag( (TAG_KEY_STR), (TAG_VALUE_STR) ); \ - FC_MULTILINE_MACRO_END + if( (fc::logger::get(DEFAULT_LOGGER)).is_enabled( fc::log_level::info ) ) \ + (fc::logger::get(DEFAULT_LOGGER)).log( FC_LOG_MESSAGE( info, FORMAT " traceID=${_the_trace_id_}", ("_the_trace_id_", TRACE_OR_SPAN->trace_id_string()) __VA_ARGS__ ) ); \ + FC_MULTILINE_MACRO_END \ No newline at end of file diff --git a/include/fc/log/zipkin.hpp b/include/fc/log/zipkin.hpp index 2017c552b..3af878547 100644 --- a/include/fc/log/zipkin.hpp +++ b/include/fc/log/zipkin.hpp @@ -34,7 +34,8 @@ class zipkin_config { /// @param timeout_us the timeout in microseconds for each http call /// (9 consecutive failures and zipkin is disabled, SIGHUP will reset the failure counter and re-enable zipkin) /// @param retry_interval_us the interval in microseconds for connecting to zipkin - static void init( const std::string& url, const std::string& service_name, uint32_t timeout_us, uint32_t retry_interval_us ); + /// @param wait_time_seconds the initial wait time in seconds for connecting to zipkin, an exception is thrown when the connection is not established within the wait time. + static void init( const std::string& url, const std::string& service_name, uint32_t timeout_us, uint32_t retry_interval_us, uint32_t wait_time_seconds = 0 ); /// Thread safe only if init() called from main thread before spawning of any threads /// @throw assert_exception if called before init() @@ -63,11 +64,14 @@ class zipkin_config { }; struct zipkin_span { - explicit zipkin_span( std::string name, uint64_t parent_id = 0 ) - : data( std::move( name ), parent_id ) {} + explicit zipkin_span( std::string name, uint64_t trace_id, uint64_t parent_id ) + : data( std::move( name ), trace_id, parent_id ) {} - explicit zipkin_span( uint64_t id, std::string name, uint64_t parent_id = 0 ) - : data( id, std::move( name ), parent_id ) {} + explicit zipkin_span( uint64_t id, std::string name, uint64_t trace_id, uint64_t parent_id ) + : data( id, std::move( name ), trace_id, parent_id ) {} + + explicit zipkin_span( std::string name, fc::time_point start ) + : data( std::move( name ), start ) {} zipkin_span( const zipkin_span& ) = delete; zipkin_span& operator=( const zipkin_span& ) = delete; @@ -112,29 +116,28 @@ struct zipkin_span { friend struct zipkin_trace; friend struct optional_trace; constexpr explicit operator bool() const noexcept { return id != 0; } + token( uint64_t id, uint64_t trace_id ) + : id( id ), trace_id( trace_id ) {} private: - explicit token( uint64_t id ) - : id( id ) {} uint64_t id; + uint64_t trace_id; }; - token get_token() const { return token{data.id}; }; + token get_token() const { return token{data.id, data.trace_id }; }; static uint64_t to_id( const fc::sha256& id ); - template - static uint64_t to_id( const T& id ) { - static_assert( std::is_same_v, "expected uint64_t" ); - return id.data()[3]; - } - struct span_data { - explicit span_data( std::string name, uint64_t parent_id = 0 ) - : id( zipkin_config::get_next_unique_id() ), parent_id( parent_id ), + explicit span_data( std::string name, uint64_t trace_id, uint64_t parent_id ) + : id( zipkin_config::get_next_unique_id() ), trace_id( trace_id ), parent_id( parent_id ), start( time_point::now() ), name( std::move( name ) ) {} - explicit span_data( uint64_t id, std::string name, uint64_t parent_id = 0 ) - : id( id ), parent_id( parent_id ), start( time_point::now() ), name( std::move( name ) ) {} + explicit span_data( uint64_t id, std::string name, uint64_t trace_id, uint64_t parent_id ) + : id( id ), trace_id( trace_id == 0 ? id : trace_id ), parent_id( parent_id ), start( time_point::now() ), name( std::move( name ) ) {} + + explicit span_data( std::string name, fc::time_point start) + : id( zipkin_config::get_next_unique_id() ), trace_id( zipkin_config::get_next_unique_id() ), parent_id( 0 ), + start( start), name( std::move( name ) ) {} span_data( const span_data& ) = delete; span_data& operator=( const span_data& ) = delete; @@ -142,44 +145,31 @@ struct zipkin_span { span_data( span_data&& rhs ) = default; uint64_t id; - // zipkin traceId and parentId are same (when parent_id set) since only allowing trace with span children. - // Not currently supporting spans with children, only trace with children spans. - const uint64_t parent_id; - const fc::time_point start; + const uint64_t trace_id; + const uint64_t parent_id; + const fc::time_point start; fc::time_point stop; std::string name; fc::mutable_variant_object tags; }; - span_data data; -}; - -struct zipkin_trace : public zipkin_span { - using zipkin_span::zipkin_span; - [[nodiscard]] std::optional create_span( std::string name ) const { - return zipkin_span{std::move( name ), get_token().id}; + return create_span_from_token(get_token(), std::move(name)); } [[nodiscard]] static std::optional create_span_from_token( zipkin_span::token token, std::string name ) { - return zipkin_span{std::move( name ), token.id}; + return zipkin_span{std::move( name ), token.trace_id, token.id}; } -}; -struct optional_trace { - std::optional opt; + std::string trace_id_string() const; - constexpr explicit operator bool() const noexcept { return opt.has_value(); } - - [[nodiscard]] zipkin_span::token get_token() const { - return opt ? opt->get_token() : zipkin_span::token( 0 ); - } + span_data data; }; class zipkin { public: - zipkin( const std::string& url, const std::string& service_name, uint32_t timeout_us, uint32_t retry_interval_us ); + zipkin( const std::string& url, const std::string& service_name, uint32_t timeout_us, uint32_t retry_interval_us , uint32_t wait_time_seconds ); /// finishes logging all queued up spans ~zipkin() = default; diff --git a/include/fc/network/http/http_client.hpp b/include/fc/network/http/http_client.hpp index 47a38f434..84dd5891d 100644 --- a/include/fc/network/http/http_client.hpp +++ b/include/fc/network/http/http_client.hpp @@ -9,6 +9,7 @@ #include #include #include +#include namespace fc { @@ -17,13 +18,21 @@ class http_client { http_client(); ~http_client(); - variant post_sync(const url& dest, const variant& payload, const time_point& deadline = time_point::maximum()); - - template - variant post_sync(const url& dest, const T& payload, const time_point& deadline = time_point::maximum()) { - variant payload_v; - to_variant(payload, payload_v); - return post_sync(dest, payload_v, deadline); + variant + post_sync(const url &dest, const variant &payload, + const time_point &deadline = time_point::maximum(), + json::output_formatting formatting = + json::output_formatting::stringify_large_ints_and_doubles); + + template + variant + post_sync(const url &dest, const T &payload, + const time_point &deadline = time_point::maximum(), + json::output_formatting formatting = + json::output_formatting::stringify_large_ints_and_doubles) { + variant payload_v; + to_variant(payload, payload_v); + return post_sync(dest, payload_v, deadline, formatting); } void add_cert(const std::string& cert_pem_string); diff --git a/src/log/zipkin.cpp b/src/log/zipkin.cpp index 5632f32a8..c45ca1ea4 100644 --- a/src/log/zipkin.cpp +++ b/src/log/zipkin.cpp @@ -18,13 +18,56 @@ namespace { namespace fc { +struct local_endpoint_resolver { + using tcp = boost::asio::ip::tcp; + using error_code = boost::system::error_code; + + local_endpoint_resolver() + : resolver(ctx) + , sock(ctx) + , timer(ctx) {} + boost::asio::io_context ctx; + tcp::resolver resolver; + tcp::socket sock; + boost::asio::deadline_timer timer; + std::string remote; + tcp::resolver::results_type endpoints; + std::optional local_endpoint; + + void async_resolve(std::string remote_host, std::string port) { + remote = remote_host + ":" + port; + resolver.async_resolve(remote_host, port, [this](const error_code& ec, tcp::resolver::results_type resolved) { + if (ec) + throw boost::system::system_error(ec); + endpoints = resolved; + do_connect(); + }); + } + + void do_connect() { + boost::asio::async_connect(sock, endpoints, [this](const error_code& ec, const tcp::endpoint& endpoint) { + if (ec) { + wlog("failed to connect to ${remote}, retry in 5 seconds", ("remote", remote)); + timer.expires_from_now(boost::posix_time::seconds(5)); + timer.async_wait([this](const error_code& ec) { + if (!ec) + do_connect(); + }); + return; + } + local_endpoint = sock.local_endpoint(); + ilog("connected to ${remote}", ("remote", remote)); + }); + } +}; + zipkin_config& zipkin_config::get() { static zipkin_config the_one; return the_one; } -void zipkin_config::init( const std::string& url, const std::string& service_name, uint32_t timeout_us, uint32_t retry_interval_us ) { - get().zip = std::make_unique( url, service_name, timeout_us, retry_interval_us ); +void zipkin_config::init( const std::string& url, const std::string& service_name, uint32_t timeout_us, uint32_t retry_interval_us, uint32_t wait_time_seconds ) { + get().zip = std::make_unique( url, service_name, timeout_us, retry_interval_us, wait_time_seconds ); } zipkin& zipkin_config::get_zipkin() { @@ -74,6 +117,8 @@ class zipkin::impl { boost::asio::deadline_timer timer{ctx}; boost::asio::io_context::strand work_strand{ctx}; boost::asio::executor_work_guard work_guard = boost::asio::make_work_guard(ctx); + std::optional local_endpoint; + impl( std::string url, std::string service_name, uint32_t timeout_us, uint32_t retry_interval_us ) : zipkin_url( std::move(url) ) @@ -82,7 +127,7 @@ class zipkin::impl { , retry_interval_us( retry_interval_us ) { } - void init(); + void init(uint32_t wait_time_seconds); void shutdown(); void log( zipkin_span::span_data&& span ); @@ -90,7 +135,24 @@ class zipkin::impl { ~impl(); }; -void zipkin::impl::init() { +void zipkin::impl::init(uint32_t wait_time_seconds) { + if (wait_time_seconds > 0) { + endpoint = url( zipkin_url ); + if (!endpoint->host() || endpoint->host()->empty()) + FC_THROW("Invalid url ${url}", ("url", zipkin_url)); + + local_endpoint_resolver resolver; + resolver.async_resolve(*endpoint->host(), std::to_string(*endpoint->port())); + auto deadline = std::chrono::system_clock::now() + std::chrono::seconds(wait_time_seconds); + resolver.ctx.run_until(deadline); + + local_endpoint = resolver.local_endpoint; + + if (!local_endpoint) { + FC_THROW("Unable to connect to ${url} within ${wait_time_seconds} seconds", ("url", zipkin_url)("wait_time_seconds", wait_time_seconds)); + } + } + thread = std::thread( [this]() { fc::set_os_thread_name( "zipkin" ); while( true ) { @@ -116,9 +178,9 @@ void zipkin::impl::shutdown() { thread.join(); } -zipkin::zipkin( const std::string& url, const std::string& service_name, uint32_t timeout_us, uint32_t retry_interval_us ) : +zipkin::zipkin( const std::string& url, const std::string& service_name, uint32_t timeout_us, uint32_t retry_interval_us, uint32_t wait_time_seconds ) : my( new impl( url, service_name, timeout_us, retry_interval_us ) ) { - my->init(); + my->init(wait_time_seconds); } uint64_t zipkin::get_next_unique_id() { @@ -135,7 +197,7 @@ void zipkin::shutdown() { my->shutdown(); } -fc::variant create_zipkin_variant( zipkin_span::span_data&& span, const std::string& service_name ) { +fc::variant create_zipkin_variant( zipkin_span::span_data&& span, const std::string& service_name, std::optional& local_endpoint ) { // https://zipkin.io/zipkin-api/ // std::string traceId; // [a-f0-9]{16,32} unique id for trace, all children spans shared same id // std::string name; // logical operation, should have low cardinality @@ -144,23 +206,22 @@ fc::variant create_zipkin_variant( zipkin_span::span_data&& span, const std::str // int64_t timestamp // epoch microseconds of start of span // int64_t duration // microseconds of span - uint64_t trace_id; - if( span.parent_id != 0 ) { - trace_id = span.parent_id; - } else { - trace_id = span.id; - } - fc::mutable_variant_object mvo; mvo( "id", fc::to_hex( reinterpret_cast(&span.id), sizeof( span.id ) ) ); - mvo( "traceId", fc::to_hex( reinterpret_cast(&trace_id), sizeof( trace_id ) ) ); + mvo( "traceId", fc::to_hex( reinterpret_cast(&span.trace_id), sizeof( span.trace_id ) ) ); if( span.parent_id != 0 ) { mvo( "parentId", fc::to_hex( reinterpret_cast(&span.parent_id), sizeof( span.parent_id ) ) ); } mvo( "name", std::move( span.name ) ); mvo( "timestamp", span.start.time_since_epoch().count() ); mvo( "duration", (span.stop - span.start).count() ); - mvo( "localEndpoint", fc::variant_object( "serviceName", service_name ) ); + + mutable_variant_object local_endpoint_mvo("serviceName", service_name); + if (local_endpoint) { + const auto &address = local_endpoint->address(); + local_endpoint_mvo( address.is_v4() ? "ipv4": "ipv6", address.to_string()); + } + mvo( "localEndpoint", local_endpoint_mvo ); mvo( "tags", std::move( span.tags ) ); span.id = 0; // stop destructor of span from calling log again @@ -205,8 +266,13 @@ void zipkin::log( zipkin_span::span_data&& span ) { } void zipkin::impl::log( zipkin_span::span_data&& span ) { - if( consecutive_errors > max_consecutive_errors ) + if (consecutive_errors > max_consecutive_errors) { + wlog("consecutive_errors=${consecutive_errors} exceeds " + "limit($max_consecutive_errors)", + ("consecutive_errors", consecutive_errors.load())("max_consecutive_errors", + max_consecutive_errors)); return; + } try { auto deadline = fc::time_point::now() + fc::microseconds( timeout_us ); @@ -215,7 +281,7 @@ void zipkin::impl::log( zipkin_span::span_data&& span ) { dlog( "connecting to zipkin: ${p}", ("p", *endpoint) ); } - http.post_sync( *endpoint, create_zipkin_variant( std::move( span ), service_name ), deadline ); + http.post_sync(*endpoint, create_zipkin_variant(std::move(span), service_name, local_endpoint), deadline, fc::json::output_formatting::legacy_generator); consecutive_errors = 0; if (!connected){ @@ -250,4 +316,8 @@ zipkin_span::~zipkin_span() { } catch( ... ) {} } +std::string zipkin_span::trace_id_string() const { + return fc::to_hex(reinterpret_cast(&data.trace_id), sizeof(data.trace_id)); +} + } // fc diff --git a/src/network/http/http_client.cpp b/src/network/http/http_client.cpp index 34adb7b41..8d712a44e 100644 --- a/src/network/http/http_client.cpp +++ b/src/network/http/http_client.cpp @@ -300,7 +300,10 @@ class http_client_impl { const deadline_type& deadline; }; - variant post_sync(const url& dest, const variant& payload, const fc::time_point& _deadline) { + variant + post_sync(const url &dest, const variant &payload, + const fc::time_point &_deadline, + json::output_formatting formatting) { static const deadline_type epoch(boost::gregorian::date(1970, 1, 1)); auto deadline = epoch + boost::posix_time::microseconds(_deadline.time_since_epoch().count()); FC_ASSERT(dest.host(), "No host set on URL"); @@ -324,7 +327,7 @@ class http_client_impl { req.set(http::field::user_agent, BOOST_BEAST_VERSION_STRING); req.set(http::field::content_type, "application/json"); req.keep_alive(true); - req.body() = json::to_string(payload, _deadline); + req.body() = json::to_string(payload, _deadline, formatting); req.prepare_payload(); auto conn_iter = get_connection(dest, deadline); @@ -379,6 +382,8 @@ class http_client_impl { } } else if (res.result() == http::status::not_found) { FC_THROW("URL not found: ${url}", ("url", (std::string)dest)); + } else if (res.result() == http::status::bad_request) { + FC_THROW("Received request: ${msg}", ("msg", res.body())); } return result; @@ -432,11 +437,12 @@ http_client::http_client() } -variant http_client::post_sync(const url& dest, const variant& payload, const fc::time_point& deadline) { - if(dest.proto() == "unix") - return _my->post_sync(_my->get_unix_url(*dest.host()), payload, deadline); +variant http_client::post_sync(const url& dest, const variant& payload, const fc::time_point& deadline, + json::output_formatting formatting) { + if (dest.proto() == "unix") + return _my->post_sync(_my->get_unix_url(*dest.host()), payload, deadline, formatting); else - return _my->post_sync(dest, payload, deadline); + return _my->post_sync(dest, payload, deadline, formatting); } void http_client::add_cert(const std::string& cert_pem_string) { From c076ebac9a71f0973ba5e98bfe496ab7c574b184 Mon Sep 17 00:00:00 2001 From: Patrick Raphael Date: Tue, 28 Sep 2021 08:31:02 -0400 Subject: [PATCH 117/124] remove websocketpp --- vendor/websocketpp/.gitignore | 94 - vendor/websocketpp/.travis.yml | 21 - vendor/websocketpp/CMakeLists.txt | 261 -- vendor/websocketpp/COPYING | 145 - vendor/websocketpp/Doxyfile | 2355 ---------------- vendor/websocketpp/SConstruct | 281 -- vendor/websocketpp/changelog.md | 342 --- vendor/websocketpp/docs/faq.dox | 86 - vendor/websocketpp/docs/getting_started.dox | 27 - vendor/websocketpp/docs/handlers.dox | 165 -- vendor/websocketpp/docs/manual.css | 22 - vendor/websocketpp/docs/manual.dox | 21 - .../docs/simple_broadcast_server.cpp | 52 - .../docs/simple_count_server_thread.cpp | 65 - vendor/websocketpp/docs/tutorials.dox | 10 - .../associative_storage/CMakeLists.txt | 12 - .../associative_storage.cpp | 88 - .../examples/broadcast_server/CMakeLists.txt | 12 - .../examples/broadcast_server/SConscript | 23 - .../broadcast_server/broadcast_server.cpp | 160 -- .../examples/debug_client/CMakeLists.txt | 17 - .../examples/debug_client/SConscript | 24 - .../examples/debug_client/debug_client.cpp | 167 -- .../examples/debug_server/CMakeLists.txt | 12 - .../examples/debug_server/SConscript | 23 - .../examples/debug_server/debug_server.cpp | 174 -- .../websocketpp/examples/dev/CMakeLists.txt | 12 - vendor/websocketpp/examples/dev/SConscript | 18 - vendor/websocketpp/examples/dev/main.cpp | 200 -- .../examples/echo_client/CMakeLists.txt | 12 - .../examples/echo_client/SConscript | 23 - .../examples/echo_client/echo_client.cpp | 97 - .../examples/echo_server/CMakeLists.txt | 12 - .../examples/echo_server/SConscript | 23 - .../examples/echo_server/echo_handler.hpp | 37 - .../examples/echo_server/echo_server.cpp | 65 - .../examples/echo_server_both/CMakeLists.txt | 18 - .../examples/echo_server_both/SConscript | 24 - .../echo_server_both/echo_server_both.cpp | 87 - .../examples/echo_server_both/server.pem | 58 - .../examples/echo_server_tls/CMakeLists.txt | 18 - .../examples/echo_server_tls/SConscript | 24 - .../examples/echo_server_tls/dh.pem | 8 - .../echo_server_tls/echo_server_tls.cpp | 154 -- .../examples/echo_server_tls/server.pem | 55 - .../examples/enriched_storage/CMakeLists.txt | 12 - .../enriched_storage/enriched_storage.cpp | 87 - .../external_io_service/CMakeLists.txt | 12 - .../examples/external_io_service/SConscript | 23 - .../external_io_service.cpp | 85 - .../external_io_service/tcp_echo_server.hpp | 97 - .../examples/handler_switch/CMakeLists.txt | 12 - .../handler_switch/handler_switch.cpp | 42 - .../examples/iostream_server/CMakeLists.txt | 12 - .../examples/iostream_server/SConscript | 23 - .../iostream_server/iostream_server.cpp | 89 - .../examples/print_server/CMakeLists.txt | 12 - .../examples/print_server/SConscript | 23 - .../examples/print_server/print_server.cpp | 24 - .../examples/scratch_client/SConscript | 24 - .../scratch_client/scratch_client.cpp | 270 -- .../examples/scratch_server/SConscript | 24 - .../scratch_server/scratch_server.cpp | 106 - .../simple_broadcast_server/CMakeLists.txt | 12 - .../simple_broadcast_server.cpp | 51 - .../examples/sip_client/CMakeLists.txt | 12 - .../examples/sip_client/README.txt | 22 - .../examples/sip_client/SConscript | 23 - .../examples/sip_client/sip_client.cpp | 84 - .../subprotocol_server/CMakeLists.txt | 12 - .../examples/subprotocol_server/SConscript | 23 - .../subprotocol_server/subprotocol_server.cpp | 48 - .../examples/telemetry_client/CMakeLists.txt | 12 - .../examples/telemetry_client/SConscript | 23 - .../telemetry_client/telemetry_client.cpp | 156 -- .../examples/telemetry_server/CMakeLists.txt | 12 - .../examples/telemetry_server/SConscript | 23 - .../examples/telemetry_server/index.html | 85 - .../telemetry_server/telemetry_server.cpp | 203 -- .../examples/testee_client/CMakeLists.txt | 17 - .../examples/testee_client/SConscript | 23 - .../examples/testee_client/testee_client.cpp | 145 - .../examples/testee_server/CMakeLists.txt | 17 - .../examples/testee_server/SConscript | 23 - .../examples/testee_server/testee_server.cpp | 145 - .../examples/utility_client/CMakeLists.txt | 13 - .../examples/utility_client/SConscript | 23 - .../utility_client/utility_client.cpp | 325 --- vendor/websocketpp/readme.md | 49 - vendor/websocketpp/roadmap.md | 43 - .../test/connection/CMakeLists.txt | 12 - vendor/websocketpp/test/connection/SConscript | 25 - .../test/connection/connection.cpp | 530 ---- .../test/connection/connection_tu2.cpp | 62 - .../test/connection/connection_tu2.hpp | 51 - .../websocketpp/test/endpoint/CMakeLists.txt | 17 - vendor/websocketpp/test/endpoint/SConscript | 24 - vendor/websocketpp/test/endpoint/endpoint.cpp | 155 -- .../websocketpp/test/extension/CMakeLists.txt | 22 - vendor/websocketpp/test/extension/SConscript | 27 - .../websocketpp/test/extension/extension.cpp | 37 - .../test/extension/permessage_deflate.cpp | 649 ----- vendor/websocketpp/test/http/CMakeLists.txt | 11 - vendor/websocketpp/test/http/SConscript | 23 - vendor/websocketpp/test/http/parser.cpp | 1129 -------- vendor/websocketpp/test/http/parser_perf.cpp | 141 - vendor/websocketpp/test/logger/CMakeLists.txt | 12 - vendor/websocketpp/test/logger/SConscript | 23 - vendor/websocketpp/test/logger/basic.cpp | 145 - .../test/message_buffer/CMakeLists.txt | 17 - .../test/message_buffer/SConscript | 27 - .../websocketpp/test/message_buffer/alloc.cpp | 96 - .../test/message_buffer/message.cpp | 72 - .../websocketpp/test/message_buffer/pool.cpp | 156 -- .../test/processors/CMakeLists.txt | 59 - vendor/websocketpp/test/processors/SConscript | 47 - .../extension_permessage_compress.cpp | 198 -- vendor/websocketpp/test/processors/hybi00.cpp | 274 -- vendor/websocketpp/test/processors/hybi07.cpp | 193 -- vendor/websocketpp/test/processors/hybi08.cpp | 197 -- vendor/websocketpp/test/processors/hybi13.cpp | 693 ----- .../websocketpp/test/processors/processor.cpp | 135 - vendor/websocketpp/test/random/CMakeLists.txt | 17 - vendor/websocketpp/test/random/SConscript | 27 - vendor/websocketpp/test/random/none.cpp | 40 - .../websocketpp/test/random/random_device.cpp | 50 - vendor/websocketpp/test/roles/CMakeLists.txt | 17 - vendor/websocketpp/test/roles/SConscript | 27 - vendor/websocketpp/test/roles/client.cpp | 194 -- vendor/websocketpp/test/roles/server.cpp | 247 -- .../websocketpp/test/transport/CMakeLists.txt | 71 - vendor/websocketpp/test/transport/SConscript | 24 - .../test/transport/asio/SConscript | 32 - .../websocketpp/test/transport/asio/base.cpp | 49 - .../test/transport/asio/security.cpp | 69 - .../test/transport/asio/timers.cpp | 187 -- .../websocketpp/test/transport/hybi_util.cpp | 98 - .../test/transport/integration.cpp | 617 ----- .../test/transport/iostream/SConscript | 31 - .../test/transport/iostream/base.cpp | 33 - .../test/transport/iostream/connection.cpp | 609 ----- .../test/transport/iostream/endpoint.cpp | 41 - .../websocketpp/test/utility/CMakeLists.txt | 53 - vendor/websocketpp/test/utility/SConscript | 40 - vendor/websocketpp/test/utility/close.cpp | 125 - vendor/websocketpp/test/utility/error.cpp | 54 - vendor/websocketpp/test/utility/frame.cpp | 538 ---- vendor/websocketpp/test/utility/sha1.cpp | 81 - vendor/websocketpp/test/utility/uri.cpp | 246 -- vendor/websocketpp/test/utility/utilities.cpp | 73 - .../broadcast_tutorial/broadcast_tutorial.md | 17 - .../tutorials/chat_tutorial/chat_tutorial.md | 13 - .../tutorials/utility_client/step1.cpp | 56 - .../tutorials/utility_client/step2.cpp | 61 - .../tutorials/utility_client/step3.cpp | 81 - .../tutorials/utility_client/step4.cpp | 202 -- .../tutorials/utility_client/step5.cpp | 280 -- .../tutorials/utility_client/step6.cpp | 335 --- .../utility_client/utility_client.md | 862 ------ .../tutorials/utility_server/step1.cpp | 71 - .../tutorials/utility_server/step2.cpp | 82 - .../utility_server/utility_server.md | 181 -- .../websocketpp/websocketpp-config.cmake.in | 7 - .../websocketpp-configVersion.cmake.in | 11 - vendor/websocketpp/websocketpp/CMakeLists.txt | 2 - .../websocketpp/websocketpp/base64/base64.hpp | 178 -- vendor/websocketpp/websocketpp/client.hpp | 33 - vendor/websocketpp/websocketpp/close.hpp | 342 --- .../websocketpp/websocketpp/common/asio.hpp | 131 - .../websocketpp/common/asio_ssl.hpp | 39 - .../websocketpp/websocketpp/common/chrono.hpp | 68 - .../websocketpp/common/connection_hdl.hpp | 52 - .../websocketpp/websocketpp/common/cpp11.hpp | 162 -- .../websocketpp/common/functional.hpp | 105 - vendor/websocketpp/websocketpp/common/md5.hpp | 448 ---- .../websocketpp/websocketpp/common/memory.hpp | 89 - .../websocketpp/common/network.hpp | 106 - .../websocketpp/common/platforms.hpp | 46 - .../websocketpp/websocketpp/common/random.hpp | 82 - .../websocketpp/websocketpp/common/regex.hpp | 59 - .../websocketpp/websocketpp/common/stdint.hpp | 73 - .../websocketpp/common/system_error.hpp | 84 - .../websocketpp/websocketpp/common/thread.hpp | 84 - .../websocketpp/websocketpp/common/time.hpp | 56 - .../websocketpp/common/type_traits.hpp | 65 - .../websocketpp/concurrency/basic.hpp | 46 - .../websocketpp/concurrency/none.hpp | 80 - .../websocketpp/websocketpp/config/asio.hpp | 77 - .../websocketpp/config/asio_client.hpp | 77 - .../websocketpp/config/asio_no_tls.hpp | 73 - .../websocketpp/config/asio_no_tls_client.hpp | 73 - .../websocketpp/config/boost_config.hpp | 72 - .../websocketpp/websocketpp/config/core.hpp | 285 -- .../websocketpp/config/core_client.hpp | 294 -- .../websocketpp/websocketpp/config/debug.hpp | 286 -- .../websocketpp/config/debug_asio.hpp | 77 - .../websocketpp/config/debug_asio_no_tls.hpp | 73 - .../websocketpp/config/minimal_client.hpp | 72 - .../websocketpp/config/minimal_server.hpp | 312 --- vendor/websocketpp/websocketpp/connection.hpp | 1652 ------------ .../websocketpp/connection_base.hpp | 38 - vendor/websocketpp/websocketpp/endpoint.hpp | 700 ----- .../websocketpp/websocketpp/endpoint_base.hpp | 38 - vendor/websocketpp/websocketpp/error.hpp | 277 -- .../websocketpp/extensions/extension.hpp | 102 - .../permessage_deflate/disabled.hpp | 128 - .../extensions/permessage_deflate/enabled.hpp | 752 ------ vendor/websocketpp/websocketpp/frame.hpp | 861 ------ .../websocketpp/http/constants.hpp | 308 --- .../websocketpp/http/impl/parser.hpp | 196 -- .../websocketpp/http/impl/request.hpp | 191 -- .../websocketpp/http/impl/response.hpp | 266 -- .../websocketpp/websocketpp/http/parser.hpp | 619 ----- .../websocketpp/websocketpp/http/request.hpp | 124 - .../websocketpp/websocketpp/http/response.hpp | 188 -- .../websocketpp/impl/connection_impl.hpp | 2384 ----------------- .../websocketpp/impl/endpoint_impl.hpp | 269 -- .../websocketpp/impl/utilities_impl.hpp | 87 - .../websocketpp/websocketpp/logger/basic.hpp | 199 -- .../websocketpp/websocketpp/logger/levels.hpp | 203 -- .../websocketpp/websocketpp/logger/stub.hpp | 119 - .../websocketpp/websocketpp/logger/syslog.hpp | 146 - .../websocketpp/message_buffer/alloc.hpp | 105 - .../websocketpp/message_buffer/message.hpp | 340 --- .../websocketpp/message_buffer/pool.hpp | 229 -- .../websocketpp/processors/base.hpp | 299 --- .../websocketpp/processors/hybi00.hpp | 462 ---- .../websocketpp/processors/hybi07.hpp | 78 - .../websocketpp/processors/hybi08.hpp | 83 - .../websocketpp/processors/hybi13.hpp | 1056 -------- .../websocketpp/processors/processor.hpp | 407 --- .../websocketpp/websocketpp/random/none.hpp | 60 - .../websocketpp/random/random_device.hpp | 80 - .../websocketpp/roles/client_endpoint.hpp | 173 -- .../websocketpp/roles/server_endpoint.hpp | 190 -- vendor/websocketpp/websocketpp/server.hpp | 33 - vendor/websocketpp/websocketpp/sha1/sha1.hpp | 189 -- .../websocketpp/transport/asio/base.hpp | 232 -- .../websocketpp/transport/asio/connection.hpp | 1204 --------- .../websocketpp/transport/asio/endpoint.hpp | 1143 -------- .../transport/asio/security/base.hpp | 159 -- .../transport/asio/security/none.hpp | 369 --- .../transport/asio/security/tls.hpp | 479 ---- .../websocketpp/transport/base/connection.hpp | 238 -- .../websocketpp/transport/base/endpoint.hpp | 77 - .../websocketpp/transport/debug/base.hpp | 104 - .../transport/debug/connection.hpp | 412 --- .../websocketpp/transport/debug/endpoint.hpp | 140 - .../websocketpp/transport/iostream/base.hpp | 133 - .../transport/iostream/connection.hpp | 714 ----- .../transport/iostream/endpoint.hpp | 222 -- .../websocketpp/transport/stub/base.hpp | 95 - .../websocketpp/transport/stub/connection.hpp | 286 -- .../websocketpp/transport/stub/endpoint.hpp | 140 - vendor/websocketpp/websocketpp/uri.hpp | 355 --- .../websocketpp/utf8_validator.hpp | 154 -- vendor/websocketpp/websocketpp/utilities.hpp | 182 -- vendor/websocketpp/websocketpp/version.hpp | 61 - 258 files changed, 44144 deletions(-) delete mode 100644 vendor/websocketpp/.gitignore delete mode 100644 vendor/websocketpp/.travis.yml delete mode 100644 vendor/websocketpp/CMakeLists.txt delete mode 100644 vendor/websocketpp/COPYING delete mode 100644 vendor/websocketpp/Doxyfile delete mode 100644 vendor/websocketpp/SConstruct delete mode 100644 vendor/websocketpp/changelog.md delete mode 100644 vendor/websocketpp/docs/faq.dox delete mode 100644 vendor/websocketpp/docs/getting_started.dox delete mode 100644 vendor/websocketpp/docs/handlers.dox delete mode 100644 vendor/websocketpp/docs/manual.css delete mode 100644 vendor/websocketpp/docs/manual.dox delete mode 100644 vendor/websocketpp/docs/simple_broadcast_server.cpp delete mode 100644 vendor/websocketpp/docs/simple_count_server_thread.cpp delete mode 100644 vendor/websocketpp/docs/tutorials.dox delete mode 100644 vendor/websocketpp/examples/associative_storage/CMakeLists.txt delete mode 100644 vendor/websocketpp/examples/associative_storage/associative_storage.cpp delete mode 100644 vendor/websocketpp/examples/broadcast_server/CMakeLists.txt delete mode 100644 vendor/websocketpp/examples/broadcast_server/SConscript delete mode 100644 vendor/websocketpp/examples/broadcast_server/broadcast_server.cpp delete mode 100644 vendor/websocketpp/examples/debug_client/CMakeLists.txt delete mode 100644 vendor/websocketpp/examples/debug_client/SConscript delete mode 100644 vendor/websocketpp/examples/debug_client/debug_client.cpp delete mode 100644 vendor/websocketpp/examples/debug_server/CMakeLists.txt delete mode 100644 vendor/websocketpp/examples/debug_server/SConscript delete mode 100644 vendor/websocketpp/examples/debug_server/debug_server.cpp delete mode 100644 vendor/websocketpp/examples/dev/CMakeLists.txt delete mode 100644 vendor/websocketpp/examples/dev/SConscript delete mode 100644 vendor/websocketpp/examples/dev/main.cpp delete mode 100644 vendor/websocketpp/examples/echo_client/CMakeLists.txt delete mode 100644 vendor/websocketpp/examples/echo_client/SConscript delete mode 100644 vendor/websocketpp/examples/echo_client/echo_client.cpp delete mode 100644 vendor/websocketpp/examples/echo_server/CMakeLists.txt delete mode 100644 vendor/websocketpp/examples/echo_server/SConscript delete mode 100644 vendor/websocketpp/examples/echo_server/echo_handler.hpp delete mode 100644 vendor/websocketpp/examples/echo_server/echo_server.cpp delete mode 100644 vendor/websocketpp/examples/echo_server_both/CMakeLists.txt delete mode 100644 vendor/websocketpp/examples/echo_server_both/SConscript delete mode 100644 vendor/websocketpp/examples/echo_server_both/echo_server_both.cpp delete mode 100644 vendor/websocketpp/examples/echo_server_both/server.pem delete mode 100644 vendor/websocketpp/examples/echo_server_tls/CMakeLists.txt delete mode 100644 vendor/websocketpp/examples/echo_server_tls/SConscript delete mode 100644 vendor/websocketpp/examples/echo_server_tls/dh.pem delete mode 100644 vendor/websocketpp/examples/echo_server_tls/echo_server_tls.cpp delete mode 100644 vendor/websocketpp/examples/echo_server_tls/server.pem delete mode 100644 vendor/websocketpp/examples/enriched_storage/CMakeLists.txt delete mode 100644 vendor/websocketpp/examples/enriched_storage/enriched_storage.cpp delete mode 100644 vendor/websocketpp/examples/external_io_service/CMakeLists.txt delete mode 100644 vendor/websocketpp/examples/external_io_service/SConscript delete mode 100644 vendor/websocketpp/examples/external_io_service/external_io_service.cpp delete mode 100644 vendor/websocketpp/examples/external_io_service/tcp_echo_server.hpp delete mode 100644 vendor/websocketpp/examples/handler_switch/CMakeLists.txt delete mode 100644 vendor/websocketpp/examples/handler_switch/handler_switch.cpp delete mode 100644 vendor/websocketpp/examples/iostream_server/CMakeLists.txt delete mode 100644 vendor/websocketpp/examples/iostream_server/SConscript delete mode 100644 vendor/websocketpp/examples/iostream_server/iostream_server.cpp delete mode 100644 vendor/websocketpp/examples/print_server/CMakeLists.txt delete mode 100644 vendor/websocketpp/examples/print_server/SConscript delete mode 100644 vendor/websocketpp/examples/print_server/print_server.cpp delete mode 100644 vendor/websocketpp/examples/scratch_client/SConscript delete mode 100644 vendor/websocketpp/examples/scratch_client/scratch_client.cpp delete mode 100644 vendor/websocketpp/examples/scratch_server/SConscript delete mode 100644 vendor/websocketpp/examples/scratch_server/scratch_server.cpp delete mode 100644 vendor/websocketpp/examples/simple_broadcast_server/CMakeLists.txt delete mode 100644 vendor/websocketpp/examples/simple_broadcast_server/simple_broadcast_server.cpp delete mode 100644 vendor/websocketpp/examples/sip_client/CMakeLists.txt delete mode 100644 vendor/websocketpp/examples/sip_client/README.txt delete mode 100644 vendor/websocketpp/examples/sip_client/SConscript delete mode 100644 vendor/websocketpp/examples/sip_client/sip_client.cpp delete mode 100644 vendor/websocketpp/examples/subprotocol_server/CMakeLists.txt delete mode 100644 vendor/websocketpp/examples/subprotocol_server/SConscript delete mode 100644 vendor/websocketpp/examples/subprotocol_server/subprotocol_server.cpp delete mode 100644 vendor/websocketpp/examples/telemetry_client/CMakeLists.txt delete mode 100644 vendor/websocketpp/examples/telemetry_client/SConscript delete mode 100644 vendor/websocketpp/examples/telemetry_client/telemetry_client.cpp delete mode 100644 vendor/websocketpp/examples/telemetry_server/CMakeLists.txt delete mode 100644 vendor/websocketpp/examples/telemetry_server/SConscript delete mode 100644 vendor/websocketpp/examples/telemetry_server/index.html delete mode 100644 vendor/websocketpp/examples/telemetry_server/telemetry_server.cpp delete mode 100644 vendor/websocketpp/examples/testee_client/CMakeLists.txt delete mode 100644 vendor/websocketpp/examples/testee_client/SConscript delete mode 100644 vendor/websocketpp/examples/testee_client/testee_client.cpp delete mode 100644 vendor/websocketpp/examples/testee_server/CMakeLists.txt delete mode 100644 vendor/websocketpp/examples/testee_server/SConscript delete mode 100644 vendor/websocketpp/examples/testee_server/testee_server.cpp delete mode 100644 vendor/websocketpp/examples/utility_client/CMakeLists.txt delete mode 100644 vendor/websocketpp/examples/utility_client/SConscript delete mode 100644 vendor/websocketpp/examples/utility_client/utility_client.cpp delete mode 100644 vendor/websocketpp/readme.md delete mode 100644 vendor/websocketpp/roadmap.md delete mode 100644 vendor/websocketpp/test/connection/CMakeLists.txt delete mode 100644 vendor/websocketpp/test/connection/SConscript delete mode 100644 vendor/websocketpp/test/connection/connection.cpp delete mode 100644 vendor/websocketpp/test/connection/connection_tu2.cpp delete mode 100644 vendor/websocketpp/test/connection/connection_tu2.hpp delete mode 100644 vendor/websocketpp/test/endpoint/CMakeLists.txt delete mode 100644 vendor/websocketpp/test/endpoint/SConscript delete mode 100644 vendor/websocketpp/test/endpoint/endpoint.cpp delete mode 100644 vendor/websocketpp/test/extension/CMakeLists.txt delete mode 100644 vendor/websocketpp/test/extension/SConscript delete mode 100644 vendor/websocketpp/test/extension/extension.cpp delete mode 100644 vendor/websocketpp/test/extension/permessage_deflate.cpp delete mode 100644 vendor/websocketpp/test/http/CMakeLists.txt delete mode 100644 vendor/websocketpp/test/http/SConscript delete mode 100644 vendor/websocketpp/test/http/parser.cpp delete mode 100644 vendor/websocketpp/test/http/parser_perf.cpp delete mode 100644 vendor/websocketpp/test/logger/CMakeLists.txt delete mode 100644 vendor/websocketpp/test/logger/SConscript delete mode 100644 vendor/websocketpp/test/logger/basic.cpp delete mode 100644 vendor/websocketpp/test/message_buffer/CMakeLists.txt delete mode 100644 vendor/websocketpp/test/message_buffer/SConscript delete mode 100644 vendor/websocketpp/test/message_buffer/alloc.cpp delete mode 100644 vendor/websocketpp/test/message_buffer/message.cpp delete mode 100644 vendor/websocketpp/test/message_buffer/pool.cpp delete mode 100644 vendor/websocketpp/test/processors/CMakeLists.txt delete mode 100644 vendor/websocketpp/test/processors/SConscript delete mode 100644 vendor/websocketpp/test/processors/extension_permessage_compress.cpp delete mode 100644 vendor/websocketpp/test/processors/hybi00.cpp delete mode 100644 vendor/websocketpp/test/processors/hybi07.cpp delete mode 100644 vendor/websocketpp/test/processors/hybi08.cpp delete mode 100644 vendor/websocketpp/test/processors/hybi13.cpp delete mode 100644 vendor/websocketpp/test/processors/processor.cpp delete mode 100644 vendor/websocketpp/test/random/CMakeLists.txt delete mode 100644 vendor/websocketpp/test/random/SConscript delete mode 100644 vendor/websocketpp/test/random/none.cpp delete mode 100644 vendor/websocketpp/test/random/random_device.cpp delete mode 100644 vendor/websocketpp/test/roles/CMakeLists.txt delete mode 100644 vendor/websocketpp/test/roles/SConscript delete mode 100644 vendor/websocketpp/test/roles/client.cpp delete mode 100644 vendor/websocketpp/test/roles/server.cpp delete mode 100644 vendor/websocketpp/test/transport/CMakeLists.txt delete mode 100644 vendor/websocketpp/test/transport/SConscript delete mode 100644 vendor/websocketpp/test/transport/asio/SConscript delete mode 100644 vendor/websocketpp/test/transport/asio/base.cpp delete mode 100644 vendor/websocketpp/test/transport/asio/security.cpp delete mode 100644 vendor/websocketpp/test/transport/asio/timers.cpp delete mode 100644 vendor/websocketpp/test/transport/hybi_util.cpp delete mode 100644 vendor/websocketpp/test/transport/integration.cpp delete mode 100644 vendor/websocketpp/test/transport/iostream/SConscript delete mode 100644 vendor/websocketpp/test/transport/iostream/base.cpp delete mode 100644 vendor/websocketpp/test/transport/iostream/connection.cpp delete mode 100644 vendor/websocketpp/test/transport/iostream/endpoint.cpp delete mode 100644 vendor/websocketpp/test/utility/CMakeLists.txt delete mode 100644 vendor/websocketpp/test/utility/SConscript delete mode 100644 vendor/websocketpp/test/utility/close.cpp delete mode 100644 vendor/websocketpp/test/utility/error.cpp delete mode 100644 vendor/websocketpp/test/utility/frame.cpp delete mode 100644 vendor/websocketpp/test/utility/sha1.cpp delete mode 100644 vendor/websocketpp/test/utility/uri.cpp delete mode 100644 vendor/websocketpp/test/utility/utilities.cpp delete mode 100644 vendor/websocketpp/tutorials/broadcast_tutorial/broadcast_tutorial.md delete mode 100644 vendor/websocketpp/tutorials/chat_tutorial/chat_tutorial.md delete mode 100644 vendor/websocketpp/tutorials/utility_client/step1.cpp delete mode 100644 vendor/websocketpp/tutorials/utility_client/step2.cpp delete mode 100644 vendor/websocketpp/tutorials/utility_client/step3.cpp delete mode 100644 vendor/websocketpp/tutorials/utility_client/step4.cpp delete mode 100644 vendor/websocketpp/tutorials/utility_client/step5.cpp delete mode 100644 vendor/websocketpp/tutorials/utility_client/step6.cpp delete mode 100644 vendor/websocketpp/tutorials/utility_client/utility_client.md delete mode 100644 vendor/websocketpp/tutorials/utility_server/step1.cpp delete mode 100644 vendor/websocketpp/tutorials/utility_server/step2.cpp delete mode 100644 vendor/websocketpp/tutorials/utility_server/utility_server.md delete mode 100644 vendor/websocketpp/websocketpp-config.cmake.in delete mode 100644 vendor/websocketpp/websocketpp-configVersion.cmake.in delete mode 100644 vendor/websocketpp/websocketpp/CMakeLists.txt delete mode 100644 vendor/websocketpp/websocketpp/base64/base64.hpp delete mode 100644 vendor/websocketpp/websocketpp/client.hpp delete mode 100644 vendor/websocketpp/websocketpp/close.hpp delete mode 100644 vendor/websocketpp/websocketpp/common/asio.hpp delete mode 100644 vendor/websocketpp/websocketpp/common/asio_ssl.hpp delete mode 100644 vendor/websocketpp/websocketpp/common/chrono.hpp delete mode 100644 vendor/websocketpp/websocketpp/common/connection_hdl.hpp delete mode 100644 vendor/websocketpp/websocketpp/common/cpp11.hpp delete mode 100644 vendor/websocketpp/websocketpp/common/functional.hpp delete mode 100644 vendor/websocketpp/websocketpp/common/md5.hpp delete mode 100644 vendor/websocketpp/websocketpp/common/memory.hpp delete mode 100644 vendor/websocketpp/websocketpp/common/network.hpp delete mode 100644 vendor/websocketpp/websocketpp/common/platforms.hpp delete mode 100644 vendor/websocketpp/websocketpp/common/random.hpp delete mode 100644 vendor/websocketpp/websocketpp/common/regex.hpp delete mode 100644 vendor/websocketpp/websocketpp/common/stdint.hpp delete mode 100644 vendor/websocketpp/websocketpp/common/system_error.hpp delete mode 100644 vendor/websocketpp/websocketpp/common/thread.hpp delete mode 100644 vendor/websocketpp/websocketpp/common/time.hpp delete mode 100644 vendor/websocketpp/websocketpp/common/type_traits.hpp delete mode 100644 vendor/websocketpp/websocketpp/concurrency/basic.hpp delete mode 100644 vendor/websocketpp/websocketpp/concurrency/none.hpp delete mode 100644 vendor/websocketpp/websocketpp/config/asio.hpp delete mode 100644 vendor/websocketpp/websocketpp/config/asio_client.hpp delete mode 100644 vendor/websocketpp/websocketpp/config/asio_no_tls.hpp delete mode 100644 vendor/websocketpp/websocketpp/config/asio_no_tls_client.hpp delete mode 100644 vendor/websocketpp/websocketpp/config/boost_config.hpp delete mode 100644 vendor/websocketpp/websocketpp/config/core.hpp delete mode 100644 vendor/websocketpp/websocketpp/config/core_client.hpp delete mode 100644 vendor/websocketpp/websocketpp/config/debug.hpp delete mode 100644 vendor/websocketpp/websocketpp/config/debug_asio.hpp delete mode 100644 vendor/websocketpp/websocketpp/config/debug_asio_no_tls.hpp delete mode 100644 vendor/websocketpp/websocketpp/config/minimal_client.hpp delete mode 100644 vendor/websocketpp/websocketpp/config/minimal_server.hpp delete mode 100644 vendor/websocketpp/websocketpp/connection.hpp delete mode 100644 vendor/websocketpp/websocketpp/connection_base.hpp delete mode 100644 vendor/websocketpp/websocketpp/endpoint.hpp delete mode 100644 vendor/websocketpp/websocketpp/endpoint_base.hpp delete mode 100644 vendor/websocketpp/websocketpp/error.hpp delete mode 100644 vendor/websocketpp/websocketpp/extensions/extension.hpp delete mode 100644 vendor/websocketpp/websocketpp/extensions/permessage_deflate/disabled.hpp delete mode 100644 vendor/websocketpp/websocketpp/extensions/permessage_deflate/enabled.hpp delete mode 100644 vendor/websocketpp/websocketpp/frame.hpp delete mode 100644 vendor/websocketpp/websocketpp/http/constants.hpp delete mode 100644 vendor/websocketpp/websocketpp/http/impl/parser.hpp delete mode 100644 vendor/websocketpp/websocketpp/http/impl/request.hpp delete mode 100644 vendor/websocketpp/websocketpp/http/impl/response.hpp delete mode 100644 vendor/websocketpp/websocketpp/http/parser.hpp delete mode 100644 vendor/websocketpp/websocketpp/http/request.hpp delete mode 100644 vendor/websocketpp/websocketpp/http/response.hpp delete mode 100644 vendor/websocketpp/websocketpp/impl/connection_impl.hpp delete mode 100644 vendor/websocketpp/websocketpp/impl/endpoint_impl.hpp delete mode 100644 vendor/websocketpp/websocketpp/impl/utilities_impl.hpp delete mode 100644 vendor/websocketpp/websocketpp/logger/basic.hpp delete mode 100644 vendor/websocketpp/websocketpp/logger/levels.hpp delete mode 100644 vendor/websocketpp/websocketpp/logger/stub.hpp delete mode 100644 vendor/websocketpp/websocketpp/logger/syslog.hpp delete mode 100644 vendor/websocketpp/websocketpp/message_buffer/alloc.hpp delete mode 100644 vendor/websocketpp/websocketpp/message_buffer/message.hpp delete mode 100644 vendor/websocketpp/websocketpp/message_buffer/pool.hpp delete mode 100644 vendor/websocketpp/websocketpp/processors/base.hpp delete mode 100644 vendor/websocketpp/websocketpp/processors/hybi00.hpp delete mode 100644 vendor/websocketpp/websocketpp/processors/hybi07.hpp delete mode 100644 vendor/websocketpp/websocketpp/processors/hybi08.hpp delete mode 100644 vendor/websocketpp/websocketpp/processors/hybi13.hpp delete mode 100644 vendor/websocketpp/websocketpp/processors/processor.hpp delete mode 100644 vendor/websocketpp/websocketpp/random/none.hpp delete mode 100644 vendor/websocketpp/websocketpp/random/random_device.hpp delete mode 100644 vendor/websocketpp/websocketpp/roles/client_endpoint.hpp delete mode 100644 vendor/websocketpp/websocketpp/roles/server_endpoint.hpp delete mode 100644 vendor/websocketpp/websocketpp/server.hpp delete mode 100644 vendor/websocketpp/websocketpp/sha1/sha1.hpp delete mode 100644 vendor/websocketpp/websocketpp/transport/asio/base.hpp delete mode 100644 vendor/websocketpp/websocketpp/transport/asio/connection.hpp delete mode 100644 vendor/websocketpp/websocketpp/transport/asio/endpoint.hpp delete mode 100644 vendor/websocketpp/websocketpp/transport/asio/security/base.hpp delete mode 100644 vendor/websocketpp/websocketpp/transport/asio/security/none.hpp delete mode 100644 vendor/websocketpp/websocketpp/transport/asio/security/tls.hpp delete mode 100644 vendor/websocketpp/websocketpp/transport/base/connection.hpp delete mode 100644 vendor/websocketpp/websocketpp/transport/base/endpoint.hpp delete mode 100644 vendor/websocketpp/websocketpp/transport/debug/base.hpp delete mode 100644 vendor/websocketpp/websocketpp/transport/debug/connection.hpp delete mode 100644 vendor/websocketpp/websocketpp/transport/debug/endpoint.hpp delete mode 100644 vendor/websocketpp/websocketpp/transport/iostream/base.hpp delete mode 100644 vendor/websocketpp/websocketpp/transport/iostream/connection.hpp delete mode 100644 vendor/websocketpp/websocketpp/transport/iostream/endpoint.hpp delete mode 100644 vendor/websocketpp/websocketpp/transport/stub/base.hpp delete mode 100644 vendor/websocketpp/websocketpp/transport/stub/connection.hpp delete mode 100644 vendor/websocketpp/websocketpp/transport/stub/endpoint.hpp delete mode 100644 vendor/websocketpp/websocketpp/uri.hpp delete mode 100644 vendor/websocketpp/websocketpp/utf8_validator.hpp delete mode 100644 vendor/websocketpp/websocketpp/utilities.hpp delete mode 100644 vendor/websocketpp/websocketpp/version.hpp diff --git a/vendor/websocketpp/.gitignore b/vendor/websocketpp/.gitignore deleted file mode 100644 index 1d0c71514..000000000 --- a/vendor/websocketpp/.gitignore +++ /dev/null @@ -1,94 +0,0 @@ -# make .git* files visible to git -!.gitignore -!.gitattributes - -.DS_Store - -#vim stuff -*~ -*.swp - -*.o -*.so -*.so.? -*.so.?.?.? -*.a -*.dylib -lib/* - -# CMake -*.cmake -*.dir -CMakeFiles -INSTALL.* -ZERO_CHECK.* -CMakeCache.txt -install_manifest.txt - -# Windows/Visual Studio -*.vcproj* -*.sln -*.suo -*.ncb -*/Debug/* -*/*/Debug/* -bin/Debug -*/Release/* -*/*/Release/* -*/RelWithDebInfo/* -*/*/RelWithDebInfo/* - -# explicitly allow this path with /debug/ in it -!websocketpp/transport/debug/* - -objs_shared/ -objs_static/ - -examples/chat_server/chat_server -examples/echo_server/echo_server -examples/chat_client/chat_client -examples/echo_client/echo_client -test/basic/tests -libwebsocketpp.dylib.0.1.0 - -websocketpp.xcodeproj/xcuserdata/* -websocketpp.xcodeproj/project.xcworkspace/xcuserdata/* -policy_based_notes.hpp - -examples/echo_server_tls/echo_server_tls - -examples/fuzzing_client/fuzzing_client - -examples/stress_client/stress_client - -examples/broadcast_server_tls/broadcast_server - -test/basic/perf - -examples/echo_server_tls/echo_server_tls - -examples/concurrent_server/concurrent_server - -examples/fuzzing_server_tls/fuzzing_server - -examples/wsperf/wsperf - -.sconsign.dblite - -build/ -doxygen/ -examples/wsperf/wsperf_client - -*.out - -*.log -*.opensdf -*.sdf -*.vcxproj -*.vcxproj.filters -*.user -install -Makefile -bin - -Testing/Temporary/CTestCostData.txt diff --git a/vendor/websocketpp/.travis.yml b/vendor/websocketpp/.travis.yml deleted file mode 100644 index a2aa97050..000000000 --- a/vendor/websocketpp/.travis.yml +++ /dev/null @@ -1,21 +0,0 @@ -language: cpp -compiler: - - gcc -before_install: - #- sudo apt-get install libboost-chrono1.48-dev libboost-regex1.48-dev libboost-system1.48-dev libboost-thread1.48-dev libboost-test1.48-dev libboost-random1.48-dev -y - - sudo add-apt-repository -y ppa:boost-latest/ppa && sudo apt-get update -q && sudo apt-get install -y libboost-chrono1.55-dev libboost-random1.55-dev libboost-regex1.55-dev libboost-system1.55-dev libboost-thread1.55-dev libboost-test1.55-dev -env: - global: - - BOOST_INCLUDES=/usr/include - - BOOST_LIBS=/usr/lib/x86_64-linux-gnu -script: scons -j 2 && scons test -branches: - only: - - master - - develop -notifications: - recipients: - - travis@zaphoyd.com - email: - on_success: change - on_failure: always diff --git a/vendor/websocketpp/CMakeLists.txt b/vendor/websocketpp/CMakeLists.txt deleted file mode 100644 index f60caa1dc..000000000 --- a/vendor/websocketpp/CMakeLists.txt +++ /dev/null @@ -1,261 +0,0 @@ - -############ Setup project and cmake - -# Project name -project (websocketpp) - -# Minimum cmake requirement. We should require a quite recent -# cmake for the dependency find macros etc. to be up to date. -cmake_minimum_required (VERSION 2.6) - -set (WEBSOCKETPP_MAJOR_VERSION 0) -set (WEBSOCKETPP_MINOR_VERSION 7) -set (WEBSOCKETPP_PATCH_VERSION 0) -set (WEBSOCKETPP_VERSION ${WEBSOCKETPP_MAJOR_VERSION}.${WEBSOCKETPP_MINOR_VERSION}.${WEBSOCKETPP_PATCH_VERSION}) - -set_property(GLOBAL PROPERTY USE_FOLDERS ON) - -set(INSTALL_INCLUDE_DIR include CACHE PATH "Installation directory for header files") -if (WIN32 AND NOT CYGWIN) - set (DEF_INSTALL_CMAKE_DIR cmake) -else () - set (DEF_INSTALL_CMAKE_DIR lib/cmake/websocketpp) -endif () -set (INSTALL_CMAKE_DIR ${DEF_INSTALL_CMAKE_DIR} CACHE PATH "Installation directory for CMake files") - -# Make relative paths absolute (needed later on) -foreach (p INCLUDE CMAKE) - set (var INSTALL_${p}_DIR) - if (NOT IS_ABSOLUTE "${${var}}") - set (${var} "${CMAKE_INSTALL_PREFIX}/${${var}}") - endif () -endforeach () - -# Set CMake library search policy -if (COMMAND cmake_policy) - cmake_policy (SET CMP0003 NEW) - cmake_policy (SET CMP0005 NEW) -endif () - -# Disable unnecessary build types -set (CMAKE_CONFIGURATION_TYPES "Release;RelWithDebInfo;Debug" CACHE STRING "Configurations" FORCE) - -# Include our cmake macros -set (CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake) -include (CMakeHelpers) - -############ Paths - -set (WEBSOCKETPP_ROOT ${CMAKE_CURRENT_SOURCE_DIR}) -set (WEBSOCKETPP_INCLUDE ${WEBSOCKETPP_ROOT}/websocketpp) -set (WEBSOCKETPP_BUILD_ROOT ${CMAKE_CURRENT_BINARY_DIR}) -set (WEBSOCKETPP_BIN ${WEBSOCKETPP_BUILD_ROOT}/bin) -set (WEBSOCKETPP_LIB ${WEBSOCKETPP_BUILD_ROOT}/lib) - -# CMake install step prefix. I assume linux users want the prefix to -# be the default /usr or /usr/local so this is only adjusted on Windows. -# - Windows: Build the INSTALL project in your solution file. -# - Linux/OSX: make install. -if (MSVC) - set (CMAKE_INSTALL_PREFIX "${WEBSOCKETPP_ROOT}/install") -endif () - -############ Build customization - -# Override from command line "CMake -D