From 9c005828cc44982eba47509c5971236e58becd29 Mon Sep 17 00:00:00 2001 From: arkpar Date: Thu, 5 Mar 2015 18:28:32 +0100 Subject: [PATCH 1/2] refactored some exceptions for thread safety --- libdevcore/Exceptions.h | 10 ++++++++-- libethcore/Exceptions.cpp | 36 ++++++++++++++++++++---------------- libethcore/Exceptions.h | 14 +++++++------- 3 files changed, 35 insertions(+), 25 deletions(-) diff --git a/libdevcore/Exceptions.h b/libdevcore/Exceptions.h index f3f9b1bf0..ab7b489f4 100644 --- a/libdevcore/Exceptions.h +++ b/libdevcore/Exceptions.h @@ -31,7 +31,13 @@ namespace dev { // base class for all exceptions -struct Exception: virtual std::exception, virtual boost::exception { mutable std::string m_message; }; +struct Exception: virtual std::exception, virtual boost::exception +{ + Exception(std::string _message = std::string()): m_message(_message) {} + const char* what() const noexcept override { return m_message.c_str(); } +private: + std::string m_message; +}; struct BadHexCharacter: virtual Exception {}; struct RLPException: virtual Exception {}; @@ -41,7 +47,7 @@ struct NoNetworking: virtual Exception {}; struct NoUPnPDevice: virtual Exception {}; struct RootNotFound: virtual Exception {}; struct FileError: virtual Exception {}; -struct InterfaceNotSupported: virtual Exception { public: InterfaceNotSupported(std::string _f): m_f("Interface " + _f + " not supported.") {} virtual const char* what() const noexcept { return m_f.c_str(); } private: std::string m_f; }; +struct InterfaceNotSupported: virtual Exception { public: InterfaceNotSupported(std::string _f): Exception("Interface " + _f + " not supported.") {} }; // error information to be added to exceptions using errinfo_invalidSymbol = boost::error_info; diff --git a/libethcore/Exceptions.cpp b/libethcore/Exceptions.cpp index 9b07743c5..4e758da76 100644 --- a/libethcore/Exceptions.cpp +++ b/libethcore/Exceptions.cpp @@ -27,20 +27,24 @@ using namespace std; using namespace dev; using namespace dev::eth; -#if ALL_COMPILERS_ARE_CPP11 -#define ETH_RETURN_STRING(S) thread_local static string s_what; s_what = S; return s_what.c_str(); -#elsif USE_BOOST_TLS -static boost::thread_specific_ptr g_exceptionMessage; -#define ETH_RETURN_STRING(S) if (!g_exceptionMessage.get()); g_exceptionMessage.reset(new string); *g_exceptionMessage.get() = S; return g_exceptionMessage.get()->c_str(); -#else -#define ETH_RETURN_STRING(S) m_message = S; return m_message.c_str(); -#endif - -const char* InvalidBlockFormat::what() const noexcept { ETH_RETURN_STRING("Invalid block format: Bad field " + toString(m_f) + " (" + toHex(m_d) + ")"); } -const char* UncleInChain::what() const noexcept { ETH_RETURN_STRING("Uncle in block already mentioned: Uncles " + toString(m_uncles) + " (" + m_block.abridged() + ")"); } -const char* InvalidTransactionsHash::what() const noexcept { ETH_RETURN_STRING("Invalid transactions hash: header says: " + toHex(m_head.ref()) + " block is:" + toHex(m_real.ref())); } -const char* InvalidGasLimit::what() const noexcept { ETH_RETURN_STRING("Invalid gas limit (provided: " + toString(provided) + " valid:" + toString(valid) + ")"); } -const char* InvalidMinGasPrice::what() const noexcept { ETH_RETURN_STRING("Invalid minimum gas price (provided: " + toString(provided) + " limit:" + toString(limit) + ")"); } -const char* InvalidNonce::what() const noexcept { ETH_RETURN_STRING("Invalid nonce (r: " + toString(required) + " c:" + toString(candidate) + ")"); } -const char* InvalidBlockNonce::what() const noexcept { ETH_RETURN_STRING("Invalid nonce (h: " + toString(h) + " n:" + toString(n) + " d:" + toString(d) + ")"); } +InvalidBlockFormat::InvalidBlockFormat(int _f, bytesConstRef _d): + Exception("Invalid block format: Bad field " + toString(_f) + " (" + toHex(_d) + ")"), f(_f), d(_d.toBytes()) {} + +UncleInChain::UncleInChain(h256Set _uncles, h256 _block): + Exception("Uncle in block already mentioned: Uncles " + toString(_uncles) + " (" + _block.abridged() + ")"), uncles(_uncles), block(_block) {} + +InvalidTransactionsHash::InvalidTransactionsHash(h256 _head, h256 _real): + Exception("Invalid transactions hash: header says: " + toHex(_head.ref()) + " block is:" + toHex(_real.ref())), head(_head), real(_real) {} + +InvalidGasLimit::InvalidGasLimit(u256 _provided, u256 _valid): + Exception("Invalid gas limit (provided: " + toString(_provided) + " valid:" + toString(_valid) + ")"), provided(_provided), valid(_valid) {} + +InvalidMinGasPrice::InvalidMinGasPrice(u256 _provided, u256 _limit): + Exception("Invalid minimum gas price (provided: " + toString(_provided) + " limit:" + toString(_limit) + ")"), provided(_provided), limit(_limit) {} + +InvalidNonce::InvalidNonce(u256 _required, u256 _candidate): + Exception("Invalid nonce (r: " + toString(_required) + " c:" + toString(_candidate) + ")"), required(_required), candidate(_candidate) {} + +InvalidBlockNonce::InvalidBlockNonce(h256 _h, h256 _n, u256 _d): + Exception("Invalid nonce (h: " + toString(h) + " n:" + toString(n) + " d:" + toString(d) + ")"), h(_h), n(_n), d(_d) {} diff --git a/libethcore/Exceptions.h b/libethcore/Exceptions.h index 3fd62afbd..21015cf6f 100644 --- a/libethcore/Exceptions.h +++ b/libethcore/Exceptions.h @@ -44,26 +44,26 @@ struct FeeTooSmall: virtual dev::Exception {}; struct TooMuchGasUsed: virtual dev::Exception {}; struct ExtraDataTooBig: virtual dev::Exception {}; struct InvalidSignature: virtual dev::Exception {}; -class InvalidBlockFormat: virtual public dev::Exception { public: InvalidBlockFormat(int _f, bytesConstRef _d): m_f(_f), m_d(_d.toBytes()) {} int m_f; bytes m_d; virtual const char* what() const noexcept; }; +class InvalidBlockFormat: virtual public dev::Exception { public: InvalidBlockFormat(int _f, bytesConstRef _d); int f; bytes d; }; struct InvalidUnclesHash: virtual dev::Exception {}; struct InvalidUncle: virtual dev::Exception {}; struct UncleTooOld: virtual dev::Exception {}; -class UncleInChain: virtual public dev::Exception { public: UncleInChain(h256Set _uncles, h256 _block): m_uncles(_uncles), m_block(_block) {} h256Set m_uncles; h256 m_block; virtual const char* what() const noexcept; }; +class UncleInChain: virtual public dev::Exception { public: UncleInChain(h256Set _uncles, h256 _block); h256Set uncles; h256 block; }; struct DuplicateUncleNonce: virtual dev::Exception {}; struct InvalidStateRoot: virtual dev::Exception {}; struct InvalidGasUsed: virtual dev::Exception {}; -class InvalidTransactionsHash: virtual public dev::Exception { public: InvalidTransactionsHash(h256 _head, h256 _real): m_head(_head), m_real(_real) {} h256 m_head; h256 m_real; virtual const char* what() const noexcept; }; +class InvalidTransactionsHash: virtual public dev::Exception { public: InvalidTransactionsHash(h256 _head, h256 _real); h256 head; h256 real; }; struct InvalidTransaction: virtual dev::Exception {}; struct InvalidDifficulty: virtual dev::Exception {}; -class InvalidGasLimit: virtual public dev::Exception { public: InvalidGasLimit(u256 _provided = 0, u256 _valid = 0): provided(_provided), valid(_valid) {} u256 provided; u256 valid; virtual const char* what() const noexcept; }; -class InvalidMinGasPrice: virtual public dev::Exception { public: InvalidMinGasPrice(u256 _provided = 0, u256 _limit = 0): provided(_provided), limit(_limit) {} u256 provided; u256 limit; virtual const char* what() const noexcept; }; +class InvalidGasLimit: virtual public dev::Exception { public: InvalidGasLimit(u256 _provided = 0, u256 _valid = 0); u256 provided; u256 valid; }; +class InvalidMinGasPrice: virtual public dev::Exception { public: InvalidMinGasPrice(u256 _provided = 0, u256 _limit = 0); u256 provided; u256 limit; }; struct InvalidTransactionGasUsed: virtual dev::Exception {}; struct InvalidTransactionsStateRoot: virtual dev::Exception {}; struct InvalidReceiptsStateRoot: virtual dev::Exception {}; struct InvalidTimestamp: virtual dev::Exception {}; struct InvalidLogBloom: virtual dev::Exception {}; -class InvalidNonce: virtual public dev::Exception { public: InvalidNonce(u256 _required = 0, u256 _candidate = 0): required(_required), candidate(_candidate) {} u256 required; u256 candidate; virtual const char* what() const noexcept; }; -class InvalidBlockNonce: virtual public dev::Exception { public: InvalidBlockNonce(h256 _h = h256(), h256 _n = h256(), u256 _d = 0): h(_h), n(_n), d(_d) {} h256 h; h256 n; u256 d; virtual const char* what() const noexcept; }; +class InvalidNonce: virtual public dev::Exception { public: InvalidNonce(u256 _required = 0, u256 _candidate = 0); u256 required; u256 candidate; }; +class InvalidBlockNonce: virtual public dev::Exception { public: InvalidBlockNonce(h256 _h = h256(), h256 _n = h256(), u256 _d = 0); h256 h; h256 n; u256 d; }; struct InvalidParentHash: virtual dev::Exception {}; struct InvalidNumber: virtual dev::Exception {}; struct InvalidContractAddress: virtual public dev::Exception {}; From e2fe258d41eba8d3b47e639f9aa4c48c575a9c7f Mon Sep 17 00:00:00 2001 From: arkpar Date: Fri, 6 Mar 2015 01:05:57 +0100 Subject: [PATCH 2/2] Super effective exception constructor --- libdevcore/Exceptions.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libdevcore/Exceptions.h b/libdevcore/Exceptions.h index ab7b489f4..e631a3b49 100644 --- a/libdevcore/Exceptions.h +++ b/libdevcore/Exceptions.h @@ -33,7 +33,7 @@ namespace dev // base class for all exceptions struct Exception: virtual std::exception, virtual boost::exception { - Exception(std::string _message = std::string()): m_message(_message) {} + Exception(std::string _message = {}) : m_message(std::move(_message)) {} const char* what() const noexcept override { return m_message.c_str(); } private: std::string m_message;