Bitcoin Core 32.1.0
P2P Digital Currency
Loading...
Searching...
No Matches
integer.cpp
Go to the documentation of this file.
1// Copyright (c) 2019-present The Bitcoin Core developers
2// Distributed under the MIT software license, see the accompanying
3// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
5#include <arith_uint256.h>
6#include <common/args.h>
7#include <common/system.h>
8#include <compressor.h>
9#include <consensus/amount.h>
10#include <consensus/merkle.h>
11#include <core_io.h>
12#include <crypto/common.h>
13#include <crypto/siphash.h>
14#include <key_io.h>
15#include <memusage.h>
16#include <netbase.h>
17#include <policy/policy.h>
18#include <policy/settings.h>
19#include <pow.h>
20#include <protocol.h>
21#include <pubkey.h>
22#include <script/script.h>
23#include <serialize.h>
24#include <streams.h>
26#include <test/fuzz/fuzz.h>
27#include <test/fuzz/util.h>
28#include <uint256.h>
29#include <univalue.h>
30#include <util/chaintype.h>
31#include <util/check.h>
32#include <util/moneystr.h>
33#include <util/overflow.h>
34#include <util/strencodings.h>
35#include <util/string.h>
36
37#include <cassert>
38#include <chrono>
39#include <limits>
40#include <set>
41#include <vector>
42
43using util::ToString;
44
49
51{
52 if (buffer.size() < sizeof(uint256) + sizeof(uint160)) {
53 return;
54 }
55 FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
56 const uint256 u256(fuzzed_data_provider.ConsumeBytes<unsigned char>(sizeof(uint256)));
57 const uint160 u160(fuzzed_data_provider.ConsumeBytes<unsigned char>(sizeof(uint160)));
58 const uint64_t u64 = fuzzed_data_provider.ConsumeIntegral<uint64_t>();
59 const int64_t i64 = fuzzed_data_provider.ConsumeIntegral<int64_t>();
60 const uint32_t u32 = fuzzed_data_provider.ConsumeIntegral<uint32_t>();
61 const int32_t i32 = fuzzed_data_provider.ConsumeIntegral<int32_t>();
62 const uint16_t u16 = fuzzed_data_provider.ConsumeIntegral<uint16_t>();
63 const int16_t i16 = fuzzed_data_provider.ConsumeIntegral<int16_t>();
64 const uint8_t u8 = fuzzed_data_provider.ConsumeIntegral<uint8_t>();
65 const int8_t i8 = fuzzed_data_provider.ConsumeIntegral<int8_t>();
66 // We cannot assume a specific value of std::is_signed_v<char>:
67 // ConsumeIntegral<char>() instead of casting from {u,}int8_t.
68 const char ch = fuzzed_data_provider.ConsumeIntegral<char>();
69 const bool b = fuzzed_data_provider.ConsumeBool();
70 const uint64_t u64_2{fuzzed_data_provider.ConsumeIntegral<uint64_t>()};
71
72 const Consensus::Params& consensus_params = Params().GetConsensus();
73 (void)CheckProofOfWorkImpl(u256, u32, consensus_params);
74 if (u64 <= MAX_MONEY) {
75 const uint64_t compressed_money_amount = CompressAmount(u64);
76 assert(u64 == DecompressAmount(compressed_money_amount));
77 static const uint64_t compressed_money_amount_max = CompressAmount(MAX_MONEY - 1);
78 assert(compressed_money_amount <= compressed_money_amount_max);
79 } else {
80 (void)CompressAmount(u64);
81 }
82 constexpr uint256 u256_min{"0000000000000000000000000000000000000000000000000000000000000000"};
83 constexpr uint256 u256_max{"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"};
84 std::vector v256{u256, u256_min, u256_max};
85 (void)ComputeMerkleRoot(std::move(v256));
86 (void)DecompressAmount(u64);
87 {
88 if (std::optional<CAmount> parsed = ParseMoney(FormatMoney(i64))) {
89 assert(parsed.value() == i64);
90 }
91 }
92 (void)GetSizeOfCompactSize(u64);
94 if (!MultiplicationOverflow(i64, static_cast<int64_t>(u32)) && !AdditionOverflow(i64, static_cast<int64_t>(4)) && !AdditionOverflow(i64 * u32, static_cast<int64_t>(4))) {
95 (void)GetVirtualTransactionSize(i64, i64, u32);
96 }
97 (void)HexDigit(ch);
98 (void)MoneyRange(i64);
99 (void)ToString(i64);
100 (void)IsDigit(ch);
101 (void)IsSpace(ch);
102 (void)IsSwitchChar(ch);
103 (void)memusage::DynamicUsage(ch);
104 (void)memusage::DynamicUsage(i16);
105 (void)memusage::DynamicUsage(i32);
106 (void)memusage::DynamicUsage(i64);
107 (void)memusage::DynamicUsage(i8);
108 (void)memusage::DynamicUsage(u16);
109 (void)memusage::DynamicUsage(u32);
110 (void)memusage::DynamicUsage(u64);
111 (void)memusage::DynamicUsage(u8);
112 const unsigned char uch = static_cast<unsigned char>(u8);
113 (void)memusage::DynamicUsage(uch);
114 {
115 const std::set<int64_t> i64s{i64, static_cast<int64_t>(u64)};
116 const size_t dynamic_usage = memusage::DynamicUsage(i64s);
117 const size_t incremental_dynamic_usage = memusage::IncrementalDynamicUsage(i64s);
118 assert(dynamic_usage == incremental_dynamic_usage * i64s.size());
119 }
120 (void)MillisToTimeval(i64);
121 (void)SighashToStr(uch);
122 {
123 CSipHasher hasher{u64, u64_2};
124 const PresaltedSipHasher presalted_hasher{u64, u64_2};
125 hasher.Write(u256);
126 assert(presalted_hasher(u256) == hasher.Finalize());
127 uint8_t extra[4]{};
128 WriteLE32(extra, u32);
129 hasher.Write(extra);
130 assert(presalted_hasher(u256, u32) == hasher.Finalize());
131 }
132 {
133 const uint64_t data0{u160.GetUint64(0)}, data1{u160.GetUint64(1)};
134 SipHasher13UJ hasher{u64, u64_2};
135 const SipHasher13UJ fixed_hasher{u64, u64_2};
136 hasher.WriteJumbo(u256);
137 assert(fixed_hasher.Hash(u256) == hasher.Finalize());
138 hasher.Write(data0);
139 assert(fixed_hasher.Hash(u256, data0) == hasher.Finalize());
140
141 SipHasher13UJ reference{u64, u64_2};
142 SipHasher13UJ mixed{u64, u64_2};
143 reference.WriteJumbo(u256);
144 mixed.WriteJumbo(u256);
145
146 const auto write_normal{[](SipHasher13UJ& hasher, uint64_t data, bool as_jumbo) {
147 if (as_jumbo) {
148 uint256 data256{};
149 WriteLE64(data256.data(), data);
150 hasher.WriteJumbo(data256);
151 } else {
152 hasher.Write(data);
153 }
154 }};
155
156 reference.Write(data0).Write(data1);
157 write_normal(mixed, data0, b);
158 write_normal(mixed, data1, u8 & 1);
159 assert(mixed.Finalize() == reference.Finalize());
160
161 reference.WriteJumbo(u256).Write(data0);
162 assert(mixed.Hash(u256, data0) == reference.Finalize());
163 }
164 (void)ToLower(ch);
165 (void)ToUpper(ch);
166 {
167 if (std::optional<CAmount> parsed = ParseMoney(ValueFromAmount(i64).getValStr())) {
168 assert(parsed.value() == i64);
169 }
170 }
171 if (i32 >= 0 && i32 <= 16) {
173 }
174
175 const std::chrono::seconds seconds{i64};
176 assert(count_seconds(seconds) == i64);
177
178 const CScriptNum script_num{i64};
179 (void)script_num.getint();
180 (void)script_num.getvch();
181
182 const arith_uint256 au256 = UintToArith256(u256);
183 assert(ArithToUint256(au256) == u256);
184 assert(uint256::FromHex(au256.GetHex()).value() == u256);
185 (void)au256.bits();
186 (void)au256.GetCompact(/* fNegative= */ false);
187 (void)au256.GetCompact(/* fNegative= */ true);
188 (void)au256.getdouble();
189 (void)au256.GetHex();
190 (void)au256.GetLow64();
191 (void)au256.size();
192 (void)au256.ToString();
193
194 const CKeyID key_id{u160};
195 const CScriptID script_id{u160};
196
197 {
198 DataStream stream{};
199
200 uint256 deserialized_u256;
201 stream << u256;
202 stream >> deserialized_u256;
203 assert(u256 == deserialized_u256 && stream.empty());
204
205 uint160 deserialized_u160;
206 stream << u160;
207 stream >> deserialized_u160;
208 assert(u160 == deserialized_u160 && stream.empty());
209
210 uint64_t deserialized_u64;
211 stream << u64;
212 stream >> deserialized_u64;
213 assert(u64 == deserialized_u64 && stream.empty());
214
215 int64_t deserialized_i64;
216 stream << i64;
217 stream >> deserialized_i64;
218 assert(i64 == deserialized_i64 && stream.empty());
219
220 uint32_t deserialized_u32;
221 stream << u32;
222 stream >> deserialized_u32;
223 assert(u32 == deserialized_u32 && stream.empty());
224
225 int32_t deserialized_i32;
226 stream << i32;
227 stream >> deserialized_i32;
228 assert(i32 == deserialized_i32 && stream.empty());
229
230 uint16_t deserialized_u16;
231 stream << u16;
232 stream >> deserialized_u16;
233 assert(u16 == deserialized_u16 && stream.empty());
234
235 int16_t deserialized_i16;
236 stream << i16;
237 stream >> deserialized_i16;
238 assert(i16 == deserialized_i16 && stream.empty());
239
240 uint8_t deserialized_u8;
241 stream << u8;
242 stream >> deserialized_u8;
243 assert(u8 == deserialized_u8 && stream.empty());
244
245 int8_t deserialized_i8;
246 stream << i8;
247 stream >> deserialized_i8;
248 assert(i8 == deserialized_i8 && stream.empty());
249
250 bool deserialized_b;
251 stream << b;
252 stream >> deserialized_b;
253 assert(b == deserialized_b && stream.empty());
254 }
255
256 {
257 const ServiceFlags service_flags = (ServiceFlags)u64;
258 (void)MayHaveUsefulAddressDB(service_flags);
259 }
260
261 {
262 DataStream stream{};
263
264 ser_writedata64(stream, u64);
265 const uint64_t deserialized_u64 = ser_readdata64(stream);
266 assert(u64 == deserialized_u64 && stream.empty());
267
268 ser_writedata32(stream, u32);
269 const uint32_t deserialized_u32 = ser_readdata32(stream);
270 assert(u32 == deserialized_u32 && stream.empty());
271
272 ser_writedata32be(stream, u32);
273 const uint32_t deserialized_u32be = ser_readdata32be(stream);
274 assert(u32 == deserialized_u32be && stream.empty());
275
276 ser_writedata16(stream, u16);
277 const uint16_t deserialized_u16 = ser_readdata16(stream);
278 assert(u16 == deserialized_u16 && stream.empty());
279
280 ser_writedata8(stream, u8);
281 const uint8_t deserialized_u8 = ser_readdata8(stream);
282 assert(u8 == deserialized_u8 && stream.empty());
283 }
284
285 {
286 DataStream stream{};
287
288 WriteCompactSize(stream, u64);
289 try {
290 const uint64_t deserialized_u64 = ReadCompactSize(stream);
291 assert(u64 == deserialized_u64 && stream.empty());
292 } catch (const std::ios_base::failure&) {
293 }
294 }
295}
constexpr CAmount MAX_MONEY
No amount larger than this (in satoshi) is valid.
Definition amount.h:26
bool MoneyRange(const CAmount &nValue)
Definition amount.h:27
bool IsSwitchChar(char c)
Definition args.h:44
arith_uint256 UintToArith256(const uint256 &a)
uint256 ArithToUint256(const arith_uint256 &a)
std::string ToString(const T &t)
Locale-independent version of std::to_string.
Definition string.h:250
void SelectParams(const ChainType chain)
Sets the params returned by Params() to those for the given chain type.
const CChainParams & Params()
Return the currently selected parameters.
const Consensus::Params & GetConsensus() const
Definition chainparams.h:89
A reference to a CKey: the Hash160 of its serialized public key.
Definition pubkey.h:26
static int DecodeOP_N(opcodetype opcode)
Encode/decode small integers:
Definition script.h:508
static opcodetype EncodeOP_N(int n)
Definition script.h:515
A reference to a CScript: the Hash160 of its serialization.
Definition script.h:597
std::vector< unsigned char > getvch() const
Definition script.h:337
int getint() const
Definition script.h:326
General SipHash-2-4 implementation.
Definition siphash.h:99
uint64_t Finalize() const
Compute the 64-bit SipHash-2-4 of the data written so far.
Definition siphash.cpp:45
CSipHasher & Write(uint64_t data)
Hash a 64-bit integer worth of data.
Definition siphash.cpp:14
Double ended buffer combining vector and stream-like interfaces.
Definition streams.h:165
bool empty() const
Definition streams.h:199
std::vector< T > ConsumeBytes(size_t num_bytes)
Optimized SipHash-2-4 implementation for uint256.
Definition siphash.h:205
A custom weaker variant of SipHash-1-3 without padding, and supporting "jumbo" inputs.
Definition siphash.h:161
SipHasher13UJ & Write(uint64_t data) noexcept
Hash a normal 64-bit value.
Definition siphash.cpp:52
SipHasher13UJ & WriteJumbo(const uint256 &hash) noexcept
Hash a 256-bit value as a jumbo block.
Definition siphash.cpp:58
uint64_t Finalize() const noexcept
Compute the 64-bit SipHash-1-3-UJ of the data written so far.
Definition siphash.cpp:64
ALWAYS_INLINE uint64_t Hash(const uint256 &hash) const noexcept
Hash a jumbo block after the data written so far and finalize without modifying the object.
Definition siphash.h:175
256-bit unsigned big integer.
uint32_t GetCompact(bool fNegative=false) const
constexpr uint64_t GetUint64(int pos) const
Definition uint256.h:109
constexpr const unsigned char * data() const
Definition uint256.h:98
unsigned int size() const
double getdouble() const
std::string ToString() const
uint64_t GetLow64() const
std::string GetHex() const
Hex encoding of the number (with the most significant digits first).
unsigned int bits() const
Returns the position of the highest bit set plus one, or zero if the value is zero.
160-bit opaque blob.
Definition uint256.h:184
256-bit opaque blob.
Definition uint256.h:196
static std::optional< uint256 > FromHex(std::string_view str)
Definition uint256.h:198
uint64_t DecompressAmount(uint64_t x)
uint64_t CompressAmount(uint64_t n)
Compress amount.
unsigned int GetSpecialScriptSize(unsigned int nSize)
uint256 ComputeMerkleRoot(std::vector< uint256 > hashes, bool *mutated)
Compute a Merkle root from the provided leaf hashes.
Definition merkle.cpp:51
std::string SighashToStr(int32_t sighash_type)
Definition core_io.cpp:341
UniValue ValueFromAmount(const CAmount amount)
Definition core_io.cpp:283
void WriteLE32(B *ptr, uint32_t x)
Definition common.h:50
void WriteLE64(B *ptr, uint64_t x)
Definition common.h:57
unsigned int u32
unsigned char u8
#define FUZZ_TARGET(...)
Definition fuzz.h:35
signed char HexDigit(char c)
Definition hex_base.cpp:64
void initialize_integer()
Definition integer.cpp:45
std::optional< CAmount > ParseMoney(const std::string &money_string)
Parse an amount denoted in full coins.
Definition moneystr.cpp:45
std::string FormatMoney(const CAmount n)
Money parsing/formatting utilities.
Definition moneystr.cpp:19
Definition basic.cpp:11
std::string ToString(const T &t)
Locale-independent version of std::to_string.
Definition string.h:250
bool AdditionOverflow(const T i, const T j) noexcept
Definition overflow.h:17
int64_t GetVirtualTransactionSize(int64_t nWeight, int64_t nSigOpCost, unsigned int bytes_per_sigop)
Compute the virtual transaction size (weight reinterpreted as bytes).
Definition policy.cpp:395
bool CheckProofOfWorkImpl(uint256 hash, unsigned int nBits, const Consensus::Params &params)
Definition pow.cpp:161
ServiceFlags
nServices flags
Definition protocol.h:321
constexpr unsigned int GetSizeOfCompactSize(uint64_t nSize)
Compact Size size < 253 – 1 byte size <= USHRT_MAX – 3 bytes (253 + 2 bytes) size <= UINT_MAX – 5 byt...
Definition serialize.h:291
uint8_t ser_readdata8(Stream &s)
Definition serialize.h:81
void ser_writedata32be(Stream &s, uint32_t obj)
Definition serialize.h:71
void ser_writedata32(Stream &s, uint32_t obj)
Definition serialize.h:66
void ser_writedata16(Stream &s, uint16_t obj)
Definition serialize.h:61
void WriteCompactSize(SizeComputer &os, uint64_t nSize)
Definition serialize.h:1151
uint16_t ser_readdata16(Stream &s)
Definition serialize.h:87
uint64_t ser_readdata64(Stream &s)
Definition serialize.h:105
void ser_writedata8(Stream &s, uint8_t obj)
Definition serialize.h:57
uint64_t ReadCompactSize(Stream &is, bool range_check=true)
Decode a CompactSize-encoded variable-length integer.
Definition serialize.h:333
uint32_t ser_readdata32(Stream &s)
Definition serialize.h:93
void ser_writedata64(Stream &s, uint64_t obj)
Definition serialize.h:76
uint32_t ser_readdata32be(Stream &s)
Definition serialize.h:99
constexpr bool IsDigit(char c)
Tests if the given character is a decimal digit.
constexpr bool IsSpace(char c) noexcept
Tests if the given character is a whitespace character.
Parameters that influence chain consensus.
Definition params.h:88
bool MultiplicationOverflow(const T i, const T j) noexcept
Definition util.h:232
std::string ToUpper(std::string_view str)
Returns the uppercase equivalent of the given string.
std::string ToLower(std::string_view str)
Returns the lowercase equivalent of the given string.
struct timeval MillisToTimeval(int64_t nTimeout)
Convert milliseconds to a struct timeval for e.g.
Definition time.cpp:149
constexpr int64_t count_seconds(std::chrono::seconds t)
Definition time.h:97
assert(!tx.IsCoinBase())