1
+ /*
2
+ This file is part of cpp-ethereum.
3
+ cpp-ethereum is free software: you can redistribute it and/or modify
4
+ it under the terms of the GNU General Public License as published by
5
+ the Free Software Foundation, either version 3 of the License, or
6
+ (at your option) any later version.
7
+ cpp-ethereum is distributed in the hope that it will be useful,
8
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
9
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
+ GNU General Public License for more details.
11
+ You should have received a copy of the GNU General Public License
12
+ along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
13
+ */
14
+ /* * @file Common.h
15
+ * @author Gav Wood <[email protected] >
16
+ * @date 2014
17
+ *
18
+ * Very common stuff (i.e. that every other header needs except vector_ref.h).
19
+ */
20
+
21
+ #pragma once
22
+
23
+ // way to many unsigned to size_t warnings in 32 bit build
24
+ #ifdef _M_IX86
25
+ #pragma warning(disable:4244)
26
+ #endif
27
+
28
+ #if _MSC_VER && _MSC_VER < 1900
29
+ #define _ALLOW_KEYWORD_MACROS
30
+ #define noexcept throw ()
31
+ #endif
32
+
33
+ #ifdef __INTEL_COMPILER
34
+ #pragma warning(disable:3682) // call through incomplete class
35
+ #endif
36
+
37
+ #include < map>
38
+ #include < unordered_map>
39
+ #include < vector>
40
+ #include < set>
41
+ #include < unordered_set>
42
+ #include < functional>
43
+ #include < string>
44
+ #include < chrono>
45
+ #pragma warning(push)
46
+ #include < boost/version.hpp>
47
+ #if (BOOST_VERSION == 105800)
48
+ #include " boost_multiprecision_number_compare_bug_workaround.hpp"
49
+ #endif
50
+ #include < boost/multiprecision/cpp_int.hpp>
51
+ #pragma warning(pop)
52
+ #include " vector_ref.h"
53
+
54
+ // CryptoPP defines byte in the global namespace, so must we.
55
+ using byte = uint8_t ;
56
+
57
+ // Quote a given token stream to turn it into a string.
58
+ #define DEV_QUOTED_HELPER (s ) #s
59
+ #define DEV_QUOTED (s ) DEV_QUOTED_HELPER(s)
60
+
61
+ #define DEV_IGNORE_EXCEPTIONS (X ) try { X; } catch (...) {}
62
+
63
+ #define DEV_IF_NO_ELSE (X ) if (!(X)){}else
64
+ #define DEV_IF_THROWS (X ) try {X;}catch (...)
65
+
66
+ namespace dev
67
+ {
68
+
69
+ extern char const * Version;
70
+
71
+ static const std::string EmptyString;
72
+
73
+ // Binary data types.
74
+ using bytes = std::vector<byte>;
75
+ using bytesRef = vector_ref<byte>;
76
+ using bytesConstRef = vector_ref<byte const >;
77
+
78
+ template <class T >
79
+ class secure_vector
80
+ {
81
+ public:
82
+ secure_vector () {}
83
+ secure_vector (secure_vector<T> const & /* _c*/ ) = default ; // See https://github.com/ethereum/libweb3core/pull/44
84
+ explicit secure_vector (unsigned _size) : m_data(_size) {}
85
+ explicit secure_vector (unsigned _size, T _item) : m_data(_size, _item) {}
86
+ explicit secure_vector (std::vector<T> const & _c) : m_data(_c) {}
87
+ explicit secure_vector (vector_ref<T> _c) : m_data(_c.data(), _c.data() + _c.size()) {}
88
+ explicit secure_vector (vector_ref<const T> _c) : m_data(_c.data(), _c.data() + _c.size()) {}
89
+ ~secure_vector () { ref ().cleanse (); }
90
+
91
+ secure_vector<T>& operator =(secure_vector<T> const & _c)
92
+ {
93
+ if (&_c == this )
94
+ return *this ;
95
+
96
+ ref ().cleanse ();
97
+ m_data = _c.m_data ;
98
+ return *this ;
99
+ }
100
+ std::vector<T>& writable () { clear (); return m_data; }
101
+ std::vector<T> const & makeInsecure () const { return m_data; }
102
+
103
+ void clear () { ref ().cleanse (); }
104
+
105
+ vector_ref<T> ref () { return vector_ref<T>(&m_data); }
106
+ vector_ref<T const > ref () const { return vector_ref<T const >(&m_data); }
107
+
108
+ size_t size () const { return m_data.size (); }
109
+ bool empty () const { return m_data.empty (); }
110
+
111
+ void swap (secure_vector<T>& io_other) { m_data.swap (io_other.m_data ); }
112
+
113
+ private:
114
+ std::vector<T> m_data;
115
+ };
116
+
117
+ using bytesSec = secure_vector<byte>;
118
+
119
+ // Numeric types.
120
+ using bigint = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<>>;
121
+ using u64 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<64 , 64 , boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void >>;
122
+ using u128 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<128 , 128 , boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void >>;
123
+ using u256 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<256 , 256 , boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void >>;
124
+ using s256 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<256 , 256 , boost::multiprecision::signed_magnitude, boost::multiprecision::unchecked, void >>;
125
+ using u160 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<160 , 160 , boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void >>;
126
+ using s160 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<160 , 160 , boost::multiprecision::signed_magnitude, boost::multiprecision::unchecked, void >>;
127
+ using u512 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<512 , 512 , boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void >>;
128
+ using s512 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<512 , 512 , boost::multiprecision::signed_magnitude, boost::multiprecision::unchecked, void >>;
129
+ using u256s = std::vector<u256>;
130
+ using u160s = std::vector<u160>;
131
+ using u256Set = std::set<u256>;
132
+ using u160Set = std::set<u160>;
133
+
134
+ // Map types.
135
+ using StringMap = std::map<std::string, std::string>;
136
+ using BytesMap = std::map<bytes, bytes>;
137
+ using u256Map = std::map<u256, u256>;
138
+ using HexMap = std::map<bytes, bytes>;
139
+
140
+ // Hash types.
141
+ using StringHashMap = std::unordered_map<std::string, std::string>;
142
+ using u256HashMap = std::unordered_map<u256, u256>;
143
+
144
+ // String types.
145
+ using strings = std::vector<std::string>;
146
+
147
+ // Fixed-length string types.
148
+ using string32 = std::array<char , 32 >;
149
+ static const string32 ZeroString32 = { { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } };
150
+
151
+ // Null/Invalid values for convenience.
152
+ static const bytes NullBytes;
153
+ static const std::map<u256, u256> EmptyMapU256U256;
154
+ extern const u256 Invalid256;
155
+
156
+ // / Interprets @a _u as a two's complement signed number and returns the resulting s256.
157
+ inline s256 u2s (u256 _u)
158
+ {
159
+ static const bigint c_end = bigint (1 ) << 256 ;
160
+ if (boost::multiprecision::bit_test (_u, 255 ))
161
+ return s256 (-(c_end - _u));
162
+ else
163
+ return s256 (_u);
164
+ }
165
+
166
+ // / @returns the two's complement signed representation of the signed number _u.
167
+ inline u256 s2u (s256 _u)
168
+ {
169
+ static const bigint c_end = bigint (1 ) << 256 ;
170
+ if (_u >= 0 )
171
+ return u256 (_u);
172
+ else
173
+ return u256 (c_end + _u);
174
+ }
175
+
176
+ // / Converts given int to a string and appends one of a series of units according to its size.
177
+ std::string inUnits (bigint const & _b, strings const & _units);
178
+
179
+ // / @returns the smallest n >= 0 such that (1 << n) >= _x
180
+ inline unsigned int toLog2 (u256 _x)
181
+ {
182
+ unsigned ret;
183
+ for (ret = 0 ; _x >>= 1 ; ++ret) {}
184
+ return ret;
185
+ }
186
+
187
+ template <size_t n> inline u256 exp10 ()
188
+ {
189
+ return exp10<n - 1 >() * u256 (10 );
190
+ }
191
+
192
+ template <> inline u256 exp10<0 >()
193
+ {
194
+ return u256 (1 );
195
+ }
196
+
197
+ // / @returns the absolute distance between _a and _b.
198
+ template <class N >
199
+ inline N diff (N const & _a, N const & _b)
200
+ {
201
+ return std::max (_a, _b) - std::min (_a, _b);
202
+ }
203
+
204
+ // / RAII utility class whose destructor calls a given function.
205
+ class ScopeGuard
206
+ {
207
+ public:
208
+ ScopeGuard (std::function<void (void )> _f) : m_f(_f) {}
209
+ ~ScopeGuard () { m_f (); }
210
+
211
+ private:
212
+ std::function<void (void )> m_f;
213
+ };
214
+
215
+ // / Inheritable for classes that have invariants.
216
+ class HasInvariants
217
+ {
218
+ public:
219
+ // / Reimplement to specify the invariants.
220
+ virtual bool invariants () const = 0;
221
+ };
222
+
223
+ // / RAII checker for invariant assertions.
224
+ class InvariantChecker
225
+ {
226
+ public:
227
+ InvariantChecker (HasInvariants* _this, char const * _fn, char const * _file, int _line) : m_this(_this), m_function(_fn), m_file(_file), m_line(_line) { checkInvariants (_this, _fn, _file, _line, true ); }
228
+ ~InvariantChecker () { checkInvariants (m_this, m_function, m_file, m_line, false ); }
229
+ // / Check invariants are met, throw if not.
230
+ static void checkInvariants (HasInvariants const * _this, char const * _fn, char const * _file, int line, bool _pre);
231
+
232
+ private:
233
+ HasInvariants const * m_this;
234
+ char const * m_function;
235
+ char const * m_file;
236
+ int m_line;
237
+ };
238
+
239
+ // / Scope guard for invariant check in a class derived from HasInvariants.
240
+ #if ETH_DEBUG
241
+ #define DEV_INVARIANT_CHECK ::dev::InvariantChecker __dev_invariantCheck (this , BOOST_CURRENT_FUNCTION, __FILE__, __LINE__)
242
+ #define DEV_INVARIANT_CHECK_HERE ::dev::InvariantChecker::checkInvariants (this , BOOST_CURRENT_FUNCTION, __FILE__, __LINE__, true )
243
+ #else
244
+ #define DEV_INVARIANT_CHECK (void )0 ;
245
+ #define DEV_INVARIANT_CHECK_HERE (void )0 ;
246
+ #endif
247
+
248
+ // / Simple scope-based timer helper.
249
+ class TimerHelper
250
+ {
251
+ public:
252
+ TimerHelper (std::string const & _id, unsigned _msReportWhenGreater = 0 ) : m_t (std::chrono::high_resolution_clock::now()), m_id(_id), m_ms(_msReportWhenGreater) {}
253
+ ~TimerHelper ();
254
+
255
+ private:
256
+ std::chrono::high_resolution_clock::time_point m_t ;
257
+ std::string m_id;
258
+ unsigned m_ms;
259
+ };
260
+
261
+ class Timer
262
+ {
263
+ public:
264
+ Timer () { restart (); }
265
+
266
+ std::chrono::high_resolution_clock::duration duration () const { return std::chrono::high_resolution_clock::now () - m_t ; }
267
+ double elapsed () const { return std::chrono::duration_cast<std::chrono::microseconds>(duration ()).count () / 1000000.0 ; }
268
+ void restart () { m_t = std::chrono::high_resolution_clock::now (); }
269
+
270
+ private:
271
+ std::chrono::high_resolution_clock::time_point m_t ;
272
+ };
273
+
274
+ #define DEV_TIMED (S ) for (::std::pair<::dev::TimerHelper, bool > __eth_t (S, true ); __eth_t .second; __eth_t .second = false )
275
+ #define DEV_TIMED_SCOPE (S ) ::dev::TimerHelper __eth_t (S)
276
+ #if defined(_WIN32)
277
+ #define DEV_TIMED_FUNCTION DEV_TIMED_SCOPE (__FUNCSIG__)
278
+ #else
279
+ #define DEV_TIMED_FUNCTION DEV_TIMED_SCOPE (__PRETTY_FUNCTION__)
280
+ #endif
281
+
282
+ #define DEV_TIMED_ABOVE (S, MS ) for (::std::pair<::dev::TimerHelper, bool > __eth_t (::dev::TimerHelper(S, MS), true); __eth_t .second; __eth_t .second = false )
283
+ #define DEV_TIMED_SCOPE_ABOVE (S, MS ) ::dev::TimerHelper __eth_t (S, MS)
284
+ #if defined(_WIN32)
285
+ #define DEV_TIMED_FUNCTION_ABOVE (MS ) DEV_TIMED_SCOPE_ABOVE(__FUNCSIG__, MS)
286
+ #else
287
+ #define DEV_TIMED_FUNCTION_ABOVE (MS ) DEV_TIMED_SCOPE_ABOVE(__PRETTY_FUNCTION__, MS)
288
+ #endif
289
+
290
+ #ifdef _MSC_VER
291
+ // TODO.
292
+ #define DEV_UNUSED
293
+ #else
294
+ #define DEV_UNUSED __attribute__ ((unused))
295
+ #endif
296
+
297
+ enum class WithExisting : int
298
+ {
299
+ Trust = 0 ,
300
+ Verify,
301
+ Rescue,
302
+ Kill
303
+ };
304
+
305
+ // / Get the current time in seconds since the epoch in UTC
306
+ uint64_t utcTime ();
307
+
308
+ }
309
+
310
+ namespace std
311
+ {
312
+
313
+ inline dev::WithExisting max (dev::WithExisting _a, dev::WithExisting _b)
314
+ {
315
+ return static_cast <dev::WithExisting>(max (static_cast <int >(_a), static_cast <int >(_b)));
316
+ }
317
+
318
+ template <> struct hash <dev::u256>
319
+ {
320
+ size_t operator ()(dev::u256 const & _a) const
321
+ {
322
+ unsigned size = _a.backend ().size ();
323
+ auto limbs = _a.backend ().limbs ();
324
+ return boost::hash_range (limbs, limbs + size);
325
+ }
326
+ };
327
+
328
+ }
0 commit comments