diff options
Diffstat (limited to 'libdevcore/Common.h')
-rw-r--r-- | libdevcore/Common.h | 210 |
1 files changed, 210 insertions, 0 deletions
diff --git a/libdevcore/Common.h b/libdevcore/Common.h new file mode 100644 index 00000000..7d301833 --- /dev/null +++ b/libdevcore/Common.h @@ -0,0 +1,210 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>. +*/ +/** @file Common.h + * @author Gav Wood <i@gavwood.com> + * @date 2014 + * + * Very common stuff (i.e. that every other header needs except vector_ref.h). + */ + +#pragma once + +// way to many unsigned to size_t warnings in 32 bit build +#ifdef _M_IX86 +#pragma warning(disable:4244) +#endif + +#if _MSC_VER && _MSC_VER < 1900 +#define _ALLOW_KEYWORD_MACROS +#define noexcept throw() +#endif + +#ifdef __INTEL_COMPILER +#pragma warning(disable:3682) //call through incomplete class +#endif + +#include <map> +#include <unordered_map> +#include <vector> +#include <set> +#include <unordered_set> +#include <functional> +#include <string> +#include <chrono> + +#if defined(__GNUC__) +#pragma warning(push) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif // defined(__GNUC__) + +// See https://github.com/ethereum/libweb3core/commit/90680a8c25bfb48b24371b4abcacde56c181517c +// See https://svn.boost.org/trac/boost/ticket/11328 +// Bob comment - perhaps we should just HARD FAIL here with Boost-1.58.00? +// It is quite old now, and requiring end-users to use a newer Boost release is probably not unreasonable. +#include <boost/version.hpp> +#if (BOOST_VERSION == 105800) + #include "boost_multiprecision_number_compare_bug_workaround.hpp" +#endif // (BOOST_VERSION == 105800) + +#include <boost/multiprecision/cpp_int.hpp> + +#if defined(__GNUC__) +#pragma warning(pop) +#pragma GCC diagnostic pop +#endif // defined(__GNUC__) + +#include "vector_ref.h" + +// CryptoPP defines byte in the global namespace, so must we. +using byte = uint8_t; + +// Quote a given token stream to turn it into a string. +#define DEV_QUOTED_HELPER(s) #s +#define DEV_QUOTED(s) DEV_QUOTED_HELPER(s) + +#define DEV_IGNORE_EXCEPTIONS(X) try { X; } catch (...) {} + +namespace dev +{ + +// Binary data types. +using bytes = std::vector<byte>; +using bytesRef = vector_ref<byte>; +using bytesConstRef = vector_ref<byte const>; + +template <class T> +class secure_vector +{ +public: + secure_vector() {} + secure_vector(secure_vector<T> const& /*_c*/) = default; // See https://github.com/ethereum/libweb3core/pull/44 + explicit secure_vector(unsigned _size): m_data(_size) {} + explicit secure_vector(unsigned _size, T _item): m_data(_size, _item) {} + explicit secure_vector(std::vector<T> const& _c): m_data(_c) {} + explicit secure_vector(vector_ref<T> _c): m_data(_c.data(), _c.data() + _c.size()) {} + explicit secure_vector(vector_ref<const T> _c): m_data(_c.data(), _c.data() + _c.size()) {} + ~secure_vector() { ref().cleanse(); } + + secure_vector<T>& operator=(secure_vector<T> const& _c) + { + if (&_c == this) + return *this; + + ref().cleanse(); + m_data = _c.m_data; + return *this; + } + std::vector<T>& writable() { clear(); return m_data; } + std::vector<T> const& makeInsecure() const { return m_data; } + + void clear() { ref().cleanse(); } + + vector_ref<T> ref() { return vector_ref<T>(&m_data); } + vector_ref<T const> ref() const { return vector_ref<T const>(&m_data); } + + size_t size() const { return m_data.size(); } + bool empty() const { return m_data.empty(); } + + void swap(secure_vector<T>& io_other) { m_data.swap(io_other.m_data); } + +private: + std::vector<T> m_data; +}; + +using bytesSec = secure_vector<byte>; + +// Numeric types. +using bigint = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<>>; +using u64 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<64, 64, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>>; +using u128 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<128, 128, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>>; +using u256 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<256, 256, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>>; +using s256 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<256, 256, boost::multiprecision::signed_magnitude, boost::multiprecision::unchecked, void>>; +using u160 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<160, 160, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>>; +using s160 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<160, 160, boost::multiprecision::signed_magnitude, boost::multiprecision::unchecked, void>>; +using u512 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<512, 512, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>>; +using s512 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<512, 512, boost::multiprecision::signed_magnitude, boost::multiprecision::unchecked, void>>; +using u256s = std::vector<u256>; +using u160s = std::vector<u160>; +using u256Set = std::set<u256>; +using u160Set = std::set<u160>; + +// Map types. +using StringMap = std::map<std::string, std::string>; + +// Hash types. +using StringHashMap = std::unordered_map<std::string, std::string>; + +// String types. +using strings = std::vector<std::string>; +// Fixed-length string types. +using string32 = std::array<char, 32>; + +// Null/Invalid values for convenience. +static const bytes NullBytes; +extern const u256 Invalid256; + +/// Interprets @a _u as a two's complement signed number and returns the resulting s256. +inline s256 u2s(u256 _u) +{ + static const bigint c_end = bigint(1) << 256; + if (boost::multiprecision::bit_test(_u, 255)) + return s256(-(c_end - _u)); + else + return s256(_u); +} + +/// @returns the two's complement signed representation of the signed number _u. +inline u256 s2u(s256 _u) +{ + static const bigint c_end = bigint(1) << 256; + if (_u >= 0) + return u256(_u); + else + return u256(c_end + _u); +} + +template <size_t n> inline u256 exp10() +{ + return exp10<n - 1>() * u256(10); +} + +template <> inline u256 exp10<0>() +{ + return u256(1); +} + +/// RAII utility class whose destructor calls a given function. +class ScopeGuard +{ +public: + ScopeGuard(std::function<void(void)> _f): m_f(_f) {} + ~ScopeGuard() { m_f(); } + +private: + std::function<void(void)> m_f; +}; + +enum class WithExisting: int +{ + Trust = 0, + Verify, + Rescue, + Kill +}; + +} |