Bitcoin Core 28.99.0
P2P Digital Currency
integer.cpp
Go to the documentation of this file.
1// Copyright (c) 2019-2022 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<char>::value:
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
71 const Consensus::Params& consensus_params = Params().GetConsensus();
72 (void)CheckProofOfWorkImpl(u256, u32, consensus_params);
73 if (u64 <= MAX_MONEY) {
74 const uint64_t compressed_money_amount = CompressAmount(u64);
75 assert(u64 == DecompressAmount(compressed_money_amount));
76 static const uint64_t compressed_money_amount_max = CompressAmount(MAX_MONEY - 1);
77 assert(compressed_money_amount <= compressed_money_amount_max);
78 } else {
79 (void)CompressAmount(u64);
80 }
81 constexpr uint256 u256_min{"0000000000000000000000000000000000000000000000000000000000000000"};
82 constexpr uint256 u256_max{"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"};
83 const std::vector<uint256> v256{u256, u256_min, u256_max};
84 (void)ComputeMerkleRoot(v256);
85 (void)DecompressAmount(u64);
86 {
87 if (std::optional<CAmount> parsed = ParseMoney(FormatMoney(i64))) {
88 assert(parsed.value() == i64);
89 }
90 }
91 (void)GetSizeOfCompactSize(u64);
93 if (!MultiplicationOverflow(i64, static_cast<int64_t>(u32)) && !AdditionOverflow(i64, static_cast<int64_t>(4)) && !AdditionOverflow(i64 * u32, static_cast<int64_t>(4))) {
94 (void)GetVirtualTransactionSize(i64, i64, u32);
95 }
96 (void)HexDigit(ch);
97 (void)MoneyRange(i64);
98 (void)ToString(i64);
99 (void)IsDigit(ch);
100 (void)IsSpace(ch);
101 (void)IsSwitchChar(ch);
102 (void)memusage::DynamicUsage(ch);
103 (void)memusage::DynamicUsage(i16);
104 (void)memusage::DynamicUsage(i32);
105 (void)memusage::DynamicUsage(i64);
106 (void)memusage::DynamicUsage(i8);
107 (void)memusage::DynamicUsage(u16);
109 (void)memusage::DynamicUsage(u64);
111 const unsigned char uch = static_cast<unsigned char>(u8);
112 (void)memusage::DynamicUsage(uch);
113 {
114 const std::set<int64_t> i64s{i64, static_cast<int64_t>(u64)};
115 const size_t dynamic_usage = memusage::DynamicUsage(i64s);
116 const size_t incremental_dynamic_usage = memusage::IncrementalDynamicUsage(i64s);
117 assert(dynamic_usage == incremental_dynamic_usage * i64s.size());
118 }
119 (void)MillisToTimeval(i64);
120 (void)SighashToStr(uch);
121 (void)SipHashUint256(u64, u64, u256);
122 (void)SipHashUint256Extra(u64, u64, u256, u32);
123 (void)ToLower(ch);
124 (void)ToUpper(ch);
125 {
126 if (std::optional<CAmount> parsed = ParseMoney(ValueFromAmount(i64).getValStr())) {
127 assert(parsed.value() == i64);
128 }
129 }
130 if (i32 >= 0 && i32 <= 16) {
132 }
133
134 const std::chrono::seconds seconds{i64};
135 assert(count_seconds(seconds) == i64);
136
137 const CScriptNum script_num{i64};
138 (void)script_num.getint();
139 (void)script_num.getvch();
140
141 const arith_uint256 au256 = UintToArith256(u256);
142 assert(ArithToUint256(au256) == u256);
143 assert(uint256::FromHex(au256.GetHex()).value() == u256);
144 (void)au256.bits();
145 (void)au256.GetCompact(/* fNegative= */ false);
146 (void)au256.GetCompact(/* fNegative= */ true);
147 (void)au256.getdouble();
148 (void)au256.GetHex();
149 (void)au256.GetLow64();
150 (void)au256.size();
151 (void)au256.ToString();
152
153 const CKeyID key_id{u160};
154 const CScriptID script_id{u160};
155
156 {
157 DataStream stream{};
158
159 uint256 deserialized_u256;
160 stream << u256;
161 stream >> deserialized_u256;
162 assert(u256 == deserialized_u256 && stream.empty());
163
164 uint160 deserialized_u160;
165 stream << u160;
166 stream >> deserialized_u160;
167 assert(u160 == deserialized_u160 && stream.empty());
168
169 uint64_t deserialized_u64;
170 stream << u64;
171 stream >> deserialized_u64;
172 assert(u64 == deserialized_u64 && stream.empty());
173
174 int64_t deserialized_i64;
175 stream << i64;
176 stream >> deserialized_i64;
177 assert(i64 == deserialized_i64 && stream.empty());
178
179 uint32_t deserialized_u32;
180 stream << u32;
181 stream >> deserialized_u32;
182 assert(u32 == deserialized_u32 && stream.empty());
183
184 int32_t deserialized_i32;
185 stream << i32;
186 stream >> deserialized_i32;
187 assert(i32 == deserialized_i32 && stream.empty());
188
189 uint16_t deserialized_u16;
190 stream << u16;
191 stream >> deserialized_u16;
192 assert(u16 == deserialized_u16 && stream.empty());
193
194 int16_t deserialized_i16;
195 stream << i16;
196 stream >> deserialized_i16;
197 assert(i16 == deserialized_i16 && stream.empty());
198
199 uint8_t deserialized_u8;
200 stream << u8;
201 stream >> deserialized_u8;
202 assert(u8 == deserialized_u8 && stream.empty());
203
204 int8_t deserialized_i8;
205 stream << i8;
206 stream >> deserialized_i8;
207 assert(i8 == deserialized_i8 && stream.empty());
208
209 bool deserialized_b;
210 stream << b;
211 stream >> deserialized_b;
212 assert(b == deserialized_b && stream.empty());
213 }
214
215 {
216 const ServiceFlags service_flags = (ServiceFlags)u64;
217 (void)MayHaveUsefulAddressDB(service_flags);
218 }
219
220 {
221 DataStream stream{};
222
223 ser_writedata64(stream, u64);
224 const uint64_t deserialized_u64 = ser_readdata64(stream);
225 assert(u64 == deserialized_u64 && stream.empty());
226
227 ser_writedata32(stream, u32);
228 const uint32_t deserialized_u32 = ser_readdata32(stream);
229 assert(u32 == deserialized_u32 && stream.empty());
230
231 ser_writedata32be(stream, u32);
232 const uint32_t deserialized_u32be = ser_readdata32be(stream);
233 assert(u32 == deserialized_u32be && stream.empty());
234
235 ser_writedata16(stream, u16);
236 const uint16_t deserialized_u16 = ser_readdata16(stream);
237 assert(u16 == deserialized_u16 && stream.empty());
238
239 ser_writedata16be(stream, u16);
240 const uint16_t deserialized_u16be = ser_readdata16be(stream);
241 assert(u16 == deserialized_u16be && stream.empty());
242
243 ser_writedata8(stream, u8);
244 const uint8_t deserialized_u8 = ser_readdata8(stream);
245 assert(u8 == deserialized_u8 && stream.empty());
246 }
247
248 {
249 DataStream stream{};
250
251 WriteCompactSize(stream, u64);
252 try {
253 const uint64_t deserialized_u64 = ReadCompactSize(stream);
254 assert(u64 == deserialized_u64 && stream.empty());
255 } catch (const std::ios_base::failure&) {
256 }
257 }
258
259 try {
261 } catch (const NonFatalCheckError&) {
262 }
263}
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:43
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.
#define CHECK_NONFATAL(condition)
Identity function.
Definition: check.h:81
const Consensus::Params & GetConsensus() const
Definition: chainparams.h:93
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:517
static opcodetype EncodeOP_N(int n)
Definition: script.h:524
A reference to a CScript: the Hash160 of its serialization.
Definition: script.h:602
int getint() const
Definition: script.h:333
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:147
std::vector< T > ConsumeBytes(size_t num_bytes)
const std::string & getValStr() const
Definition: univalue.h:68
256-bit unsigned big integer.
uint32_t GetCompact(bool fNegative=false) const
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:178
256-bit opaque blob.
Definition: uint256.h:190
static std::optional< uint256 > FromHex(std::string_view str)
Definition: uint256.h:192
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
std::string SighashToStr(unsigned char sighash_type)
Definition: core_write.cpp:84
UniValue ValueFromAmount(const CAmount amount)
Definition: core_write.cpp:26
unsigned int u32
unsigned char u8
signed char HexDigit(char c)
Definition: hex_base.cpp:63
FUZZ_TARGET(integer,.init=initialize_integer)
Definition: integer.cpp:50
void initialize_integer()
Definition: integer.cpp:45
uint256 ComputeMerkleRoot(std::vector< uint256 > hashes, bool *mutated)
Definition: merkle.cpp:46
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
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:233
bool AdditionOverflow(const T i, const T j) noexcept
Definition: overflow.h:13
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:312
bool CheckProofOfWorkImpl(uint256 hash, unsigned int nBits, const Consensus::Params &params)
Definition: pow.cpp:146
ServiceFlags
nServices flags
Definition: protocol.h:309
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:360
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:295
uint8_t ser_readdata8(Stream &s)
Definition: serialize.h:83
void ser_writedata32be(Stream &s, uint32_t obj)
Definition: serialize.h:73
void ser_writedata32(Stream &s, uint32_t obj)
Definition: serialize.h:68
void ser_writedata16(Stream &s, uint16_t obj)
Definition: serialize.h:58
void WriteCompactSize(SizeComputer &os, uint64_t nSize)
Definition: serialize.h:1095
void ser_writedata16be(Stream &s, uint16_t obj)
Definition: serialize.h:63
uint16_t ser_readdata16(Stream &s)
Definition: serialize.h:89
uint64_t ser_readdata64(Stream &s)
Definition: serialize.h:113
void ser_writedata8(Stream &s, uint8_t obj)
Definition: serialize.h:54
uint64_t ReadCompactSize(Stream &is, bool range_check=true)
Decode a CompactSize-encoded variable-length integer.
Definition: serialize.h:337
uint32_t ser_readdata32(Stream &s)
Definition: serialize.h:101
uint16_t ser_readdata16be(Stream &s)
Definition: serialize.h:95
void ser_writedata64(Stream &s, uint64_t obj)
Definition: serialize.h:78
uint32_t ser_readdata32be(Stream &s)
Definition: serialize.h:107
uint64_t SipHashUint256Extra(uint64_t k0, uint64_t k1, const uint256 &val, uint32_t extra)
Definition: siphash.cpp:135
uint64_t SipHashUint256(uint64_t k0, uint64_t k1, const uint256 &val)
Optimized SipHash-2-4 implementation for uint256.
Definition: siphash.cpp:95
constexpr bool IsDigit(char c)
Tests if the given character is a decimal digit.
Definition: strencodings.h:150
constexpr bool IsSpace(char c) noexcept
Tests if the given character is a whitespace character.
Definition: strencodings.h:166
Parameters that influence chain consensus.
Definition: params.h:74
bool MultiplicationOverflow(const T i, const T j) noexcept
Definition: util.h:208
struct timeval MillisToTimeval(int64_t nTimeout)
Convert milliseconds to a struct timeval for e.g.
Definition: time.cpp:90
constexpr int64_t count_seconds(std::chrono::seconds t)
Definition: time.h:56
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.
assert(!tx.IsCoinBase())