Bitcoin Core  27.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 
43 using 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)CheckProofOfWork(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  static const uint256 u256_min(uint256S("0000000000000000000000000000000000000000000000000000000000000000"));
82  static const uint256 u256_max(uint256S("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);
110  (void)memusage::DynamicUsage(u8);
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(uint256S(au256.GetHex()) == 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 {
260  CHECK_NONFATAL(b);
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)
const CChainParams & Params()
Return the currently selected parameters.
void SelectParams(const ChainType chain)
Sets the params returned by Params() to those for the given chain type.
#define CHECK_NONFATAL(condition)
Identity function.
Definition: check.h:73
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:506
static opcodetype EncodeOP_N(int n)
Definition: script.h:513
A reference to a CScript: the Hash160 of its serialization.
Definition: script.h:583
int getint() const
Definition: script.h:332
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
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:115
256-bit opaque blob.
Definition: uint256.h:127
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:45
std::string FormatMoney(const CAmount n)
Money parsing/formatting utilities.
Definition: moneystr.cpp:19
std::optional< CAmount > ParseMoney(const std::string &money_string)
Parse an amount denoted in full coins.
Definition: moneystr.cpp:45
static size_t DynamicUsage(const int8_t &v)
Dynamic memory usage for built-in types is zero.
Definition: memusage.h:30
static size_t IncrementalDynamicUsage(const std::set< X, Y > &s)
Definition: memusage.h:106
std::string ToString(const T &t)
Locale-independent version of std::to_string.
Definition: string.h:148
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:295
bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params &params)
Check whether a block hash satisfies the proof-of-work requirement specified by nBits.
Definition: pow.cpp:125
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:152
constexpr bool IsSpace(char c) noexcept
Tests if the given character is a whitespace character.
Definition: strencodings.h:168
Parameters that influence chain consensus.
Definition: params.h:74
bool MultiplicationOverflow(const T i, const T j) noexcept
Definition: util.h:190
struct timeval MillisToTimeval(int64_t nTimeout)
Convert milliseconds to a struct timeval for e.g.
Definition: time.cpp:63
constexpr int64_t count_seconds(std::chrono::seconds t)
Definition: time.h:54
uint256 uint256S(std::string_view str)
Definition: uint256.h:140
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())