Bitcoin Core 31.99.0
P2P Digital Currency
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
46{
48}
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);
110 (void)memusage::DynamicUsage(u64);
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}
static 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:45
arith_uint256 UintToArith256(const uint256 &a)
uint256 ArithToUint256(const arith_uint256 &a)
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:24
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
int getint() const
Definition: script.h:326
General SipHash-2-4 implementation.
Definition: siphash.h:99
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:165
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
const std::string & getValStr() const
Definition: univalue.h:68
256-bit unsigned big integer.
uint32_t GetCompact(bool fNegative=false) const
constexpr uint64_t GetUint64(int pos) const
Definition: uint256.h:109
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
static const PrecomputedData data
Precomputed COutPoint and CCoins values.
uint64_t DecompressAmount(uint64_t x)
Definition: compressor.cpp:168
uint64_t CompressAmount(uint64_t n)
Compress amount.
Definition: compressor.cpp:149
unsigned int GetSpecialScriptSize(unsigned int nSize)
Definition: compressor.cpp:86
uint256 ComputeMerkleRoot(std::vector< uint256 > hashes, bool *mutated)
Definition: merkle.cpp:46
std::string SighashToStr(unsigned char 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
signed char HexDigit(char c)
Definition: hex_base.cpp:64
FUZZ_TARGET(integer,.init=initialize_integer)
Definition: integer.cpp:50
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:8
static size_t DynamicUsage(const int8_t &v)
Dynamic memory usage for built-in types is zero.
Definition: memusage.h:31
static size_t IncrementalDynamicUsage(const std::set< X, Y > &s)
Definition: memusage.h:119
std::string ToString(const T &t)
Locale-independent version of std::to_string.
Definition: string.h:249
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
static bool MayHaveUsefulAddressDB(ServiceFlags services)
Checks if a peer with the given service flags may be capable of having a robust address-storage DB.
Definition: protocol.h:380
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.
Definition: strencodings.h:149
constexpr bool IsSpace(char c) noexcept
Tests if the given character is a whitespace character.
Definition: strencodings.h:165
Parameters that influence chain consensus.
Definition: params.h:87
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:150
constexpr int64_t count_seconds(std::chrono::seconds t)
Definition: time.h:97
assert(!tx.IsCoinBase())
FuzzedDataProvider & fuzzed_data_provider
Definition: fees.cpp:39