Bitcoin Core 22.99.0
P2P Digital Currency
integer.cpp
Go to the documentation of this file.
1// Copyright (c) 2019-2020 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 <compressor.h>
7#include <consensus/amount.h>
8#include <consensus/merkle.h>
9#include <core_io.h>
10#include <crypto/common.h>
11#include <crypto/siphash.h>
12#include <key_io.h>
13#include <memusage.h>
14#include <netbase.h>
15#include <policy/settings.h>
16#include <pow.h>
17#include <protocol.h>
18#include <pubkey.h>
19#include <script/standard.h>
20#include <serialize.h>
21#include <streams.h>
23#include <test/fuzz/fuzz.h>
24#include <test/fuzz/util.h>
25#include <uint256.h>
26#include <univalue.h>
27#include <util/check.h>
28#include <util/moneystr.h>
29#include <util/strencodings.h>
30#include <util/string.h>
31#include <util/system.h>
32#include <util/time.h>
33#include <version.h>
34
35#include <cassert>
36#include <chrono>
37#include <ctime>
38#include <limits>
39#include <set>
40#include <vector>
41
43{
45}
46
48{
49 if (buffer.size() < sizeof(uint256) + sizeof(uint160)) {
50 return;
51 }
52 FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
53 const uint256 u256(fuzzed_data_provider.ConsumeBytes<unsigned char>(sizeof(uint256)));
54 const uint160 u160(fuzzed_data_provider.ConsumeBytes<unsigned char>(sizeof(uint160)));
55 const uint64_t u64 = fuzzed_data_provider.ConsumeIntegral<uint64_t>();
56 const int64_t i64 = fuzzed_data_provider.ConsumeIntegral<int64_t>();
57 const uint32_t u32 = fuzzed_data_provider.ConsumeIntegral<uint32_t>();
58 const int32_t i32 = fuzzed_data_provider.ConsumeIntegral<int32_t>();
59 const uint16_t u16 = fuzzed_data_provider.ConsumeIntegral<uint16_t>();
60 const int16_t i16 = fuzzed_data_provider.ConsumeIntegral<int16_t>();
61 const uint8_t u8 = fuzzed_data_provider.ConsumeIntegral<uint8_t>();
62 const int8_t i8 = fuzzed_data_provider.ConsumeIntegral<int8_t>();
63 // We cannot assume a specific value of std::is_signed<char>::value:
64 // ConsumeIntegral<char>() instead of casting from {u,}int8_t.
65 const char ch = fuzzed_data_provider.ConsumeIntegral<char>();
66 const bool b = fuzzed_data_provider.ConsumeBool();
67
68 const Consensus::Params& consensus_params = Params().GetConsensus();
69 (void)CheckProofOfWork(u256, u32, consensus_params);
70 if (u64 <= MAX_MONEY) {
71 const uint64_t compressed_money_amount = CompressAmount(u64);
72 assert(u64 == DecompressAmount(compressed_money_amount));
73 static const uint64_t compressed_money_amount_max = CompressAmount(MAX_MONEY - 1);
74 assert(compressed_money_amount <= compressed_money_amount_max);
75 } else {
76 (void)CompressAmount(u64);
77 }
78 static const uint256 u256_min(uint256S("0000000000000000000000000000000000000000000000000000000000000000"));
79 static const uint256 u256_max(uint256S("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"));
80 const std::vector<uint256> v256{u256, u256_min, u256_max};
81 (void)ComputeMerkleRoot(v256);
82 (void)CountBits(u64);
83 (void)DecompressAmount(u64);
84 (void)FormatISO8601Date(i64);
85 (void)FormatISO8601DateTime(i64);
86 {
87 if (std::optional<CAmount> parsed = ParseMoney(FormatMoney(i64))) {
88 assert(parsed.value() == i64);
89 }
90 }
91 (void)GetSizeOfCompactSize(u64);
92 (void)GetSpecialScriptSize(u32);
93 if (!MultiplicationOverflow(i64, static_cast<int64_t>(::nBytesPerSigOp)) && !AdditionOverflow(i64 * ::nBytesPerSigOp, static_cast<int64_t>(4))) {
94 (void)GetVirtualTransactionSize(i64, i64);
95 }
96 if (!MultiplicationOverflow(i64, static_cast<int64_t>(u32)) && !AdditionOverflow(i64, static_cast<int64_t>(4)) && !AdditionOverflow(i64 * u32, static_cast<int64_t>(4))) {
97 (void)GetVirtualTransactionSize(i64, i64, u32);
98 }
99 (void)HexDigit(ch);
100 (void)MoneyRange(i64);
101 (void)ToString(i64);
102 (void)IsDigit(ch);
103 (void)IsSpace(ch);
104 (void)IsSwitchChar(ch);
105 (void)memusage::DynamicUsage(ch);
106 (void)memusage::DynamicUsage(i16);
107 (void)memusage::DynamicUsage(i32);
108 (void)memusage::DynamicUsage(i64);
109 (void)memusage::DynamicUsage(i8);
110 (void)memusage::DynamicUsage(u16);
111 (void)memusage::DynamicUsage(u32);
112 (void)memusage::DynamicUsage(u64);
113 (void)memusage::DynamicUsage(u8);
114 const unsigned char uch = static_cast<unsigned char>(u8);
115 (void)memusage::DynamicUsage(uch);
116 {
117 const std::set<int64_t> i64s{i64, static_cast<int64_t>(u64)};
118 const size_t dynamic_usage = memusage::DynamicUsage(i64s);
119 const size_t incremental_dynamic_usage = memusage::IncrementalDynamicUsage(i64s);
120 assert(dynamic_usage == incremental_dynamic_usage * i64s.size());
121 }
122 (void)MillisToTimeval(i64);
123 (void)SighashToStr(uch);
124 (void)SipHashUint256(u64, u64, u256);
125 (void)SipHashUint256Extra(u64, u64, u256, u32);
126 (void)ToLower(ch);
127 (void)ToUpper(ch);
128 {
129 if (std::optional<CAmount> parsed = ParseMoney(ValueFromAmount(i64).getValStr())) {
130 assert(parsed.value() == i64);
131 }
132 }
133 if (i32 >= 0 && i32 <= 16) {
135 }
136
137 const std::chrono::seconds seconds{i64};
138 assert(count_seconds(seconds) == i64);
139
140 const CScriptNum script_num{i64};
141 (void)script_num.getint();
142 (void)script_num.getvch();
143
144 const arith_uint256 au256 = UintToArith256(u256);
145 assert(ArithToUint256(au256) == u256);
146 assert(uint256S(au256.GetHex()) == u256);
147 (void)au256.bits();
148 (void)au256.GetCompact(/* fNegative= */ false);
149 (void)au256.GetCompact(/* fNegative= */ true);
150 (void)au256.getdouble();
151 (void)au256.GetHex();
152 (void)au256.GetLow64();
153 (void)au256.size();
154 (void)au256.ToString();
155
156 const CKeyID key_id{u160};
157 const CScriptID script_id{u160};
158
159 {
161
162 uint256 deserialized_u256;
163 stream << u256;
164 stream >> deserialized_u256;
165 assert(u256 == deserialized_u256 && stream.empty());
166
167 uint160 deserialized_u160;
168 stream << u160;
169 stream >> deserialized_u160;
170 assert(u160 == deserialized_u160 && stream.empty());
171
172 uint64_t deserialized_u64;
173 stream << u64;
174 stream >> deserialized_u64;
175 assert(u64 == deserialized_u64 && stream.empty());
176
177 int64_t deserialized_i64;
178 stream << i64;
179 stream >> deserialized_i64;
180 assert(i64 == deserialized_i64 && stream.empty());
181
182 uint32_t deserialized_u32;
183 stream << u32;
184 stream >> deserialized_u32;
185 assert(u32 == deserialized_u32 && stream.empty());
186
187 int32_t deserialized_i32;
188 stream << i32;
189 stream >> deserialized_i32;
190 assert(i32 == deserialized_i32 && stream.empty());
191
192 uint16_t deserialized_u16;
193 stream << u16;
194 stream >> deserialized_u16;
195 assert(u16 == deserialized_u16 && stream.empty());
196
197 int16_t deserialized_i16;
198 stream << i16;
199 stream >> deserialized_i16;
200 assert(i16 == deserialized_i16 && stream.empty());
201
202 uint8_t deserialized_u8;
203 stream << u8;
204 stream >> deserialized_u8;
205 assert(u8 == deserialized_u8 && stream.empty());
206
207 int8_t deserialized_i8;
208 stream << i8;
209 stream >> deserialized_i8;
210 assert(i8 == deserialized_i8 && stream.empty());
211
212 char deserialized_ch;
213 stream << ch;
214 stream >> deserialized_ch;
215 assert(ch == deserialized_ch && stream.empty());
216
217 bool deserialized_b;
218 stream << b;
219 stream >> deserialized_b;
220 assert(b == deserialized_b && stream.empty());
221 }
222
223 {
224 const ServiceFlags service_flags = (ServiceFlags)u64;
225 (void)HasAllDesirableServiceFlags(service_flags);
226 (void)MayHaveUsefulAddressDB(service_flags);
227 }
228
229 {
231
232 ser_writedata64(stream, u64);
233 const uint64_t deserialized_u64 = ser_readdata64(stream);
234 assert(u64 == deserialized_u64 && stream.empty());
235
236 ser_writedata32(stream, u32);
237 const uint32_t deserialized_u32 = ser_readdata32(stream);
238 assert(u32 == deserialized_u32 && stream.empty());
239
240 ser_writedata32be(stream, u32);
241 const uint32_t deserialized_u32be = ser_readdata32be(stream);
242 assert(u32 == deserialized_u32be && stream.empty());
243
244 ser_writedata16(stream, u16);
245 const uint16_t deserialized_u16 = ser_readdata16(stream);
246 assert(u16 == deserialized_u16 && stream.empty());
247
248 ser_writedata16be(stream, u16);
249 const uint16_t deserialized_u16be = ser_readdata16be(stream);
250 assert(u16 == deserialized_u16be && stream.empty());
251
252 ser_writedata8(stream, u8);
253 const uint8_t deserialized_u8 = ser_readdata8(stream);
254 assert(u8 == deserialized_u8 && stream.empty());
255 }
256
257 {
259
260 WriteCompactSize(stream, u64);
261 try {
262 const uint64_t deserialized_u64 = ReadCompactSize(stream);
263 assert(u64 == deserialized_u64 && stream.empty());
264 } catch (const std::ios_base::failure&) {
265 }
266 }
267
268 try {
270 } catch (const NonFatalCheckError&) {
271 }
272}
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
arith_uint256 UintToArith256(const uint256 &a)
uint256 ArithToUint256(const arith_uint256 &a)
void SelectParams(const std::string &network)
Sets the params returned by Params() to those for the given chain name.
const CChainParams & Params()
Return the currently selected parameters.
#define CHECK_NONFATAL(condition)
Throw a NonFatalCheckError when the condition evaluates to false.
Definition: check.h:32
static const std::string REGTEST
const Consensus::Params & GetConsensus() const
Definition: chainparams.h:82
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:205
bool empty() const
Definition: streams.h:256
A reference to a CKey: the Hash160 of its serialized public key.
Definition: pubkey.h:23
static int DecodeOP_N(opcodetype opcode)
Encode/decode small integers:
Definition: script.h:498
static opcodetype EncodeOP_N(int n)
Definition: script.h:505
A reference to a CScript: the Hash160 of its serialization (see script.h)
Definition: standard.h:26
int getint() const
Definition: script.h:326
std::vector< T > ConsumeBytes(size_t num_bytes)
const std::string & getValStr() const
Definition: univalue.h:63
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:113
256-bit opaque blob.
Definition: uint256.h:124
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:79
UniValue ValueFromAmount(const CAmount amount)
Definition: core_write.cpp:21
static uint64_t CountBits(uint64_t x)
Return the smallest number n such that (x >> n) == 0 (or 64 if the highest bit in x is set.
Definition: common.h:90
void initialize_integer()
Definition: integer.cpp:42
FUZZ_TARGET_INIT(integer, initialize_integer)
Definition: integer.cpp:47
uint256 ComputeMerkleRoot(std::vector< uint256 > hashes, bool *mutated)
Definition: merkle.cpp:45
std::optional< CAmount > ParseMoney(const std::string &money_string)
Parse an amount denoted in full coins.
Definition: moneystr.cpp:41
std::string FormatMoney(const CAmount n)
Money parsing/formatting utilities.
Definition: moneystr.cpp:15
static size_t DynamicUsage(const int8_t &v)
Dynamic memory usage for built-in types is zero.
Definition: memusage.h:29
static size_t IncrementalDynamicUsage(const std::set< X, Y > &s)
Definition: memusage.h:105
unsigned int nBytesPerSigOp
Definition: settings.cpp:14
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:285
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:74
static bool HasAllDesirableServiceFlags(ServiceFlags services)
A shortcut for (services & GetDesirableServiceFlags(services)) == GetDesirableServiceFlags(services),...
Definition: protocol.h:343
ServiceFlags
nServices flags
Definition: protocol.h:271
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:352
@ SER_NETWORK
Definition: serialize.h:138
uint8_t ser_readdata8(Stream &s)
Definition: serialize.h:89
void ser_writedata32be(Stream &s, uint32_t obj)
Definition: serialize.h:79
void ser_writedata32(Stream &s, uint32_t obj)
Definition: serialize.h:74
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:240
void ser_writedata16(Stream &s, uint16_t obj)
Definition: serialize.h:64
void ser_writedata16be(Stream &s, uint16_t obj)
Definition: serialize.h:69
uint16_t ser_readdata16(Stream &s)
Definition: serialize.h:95
uint64_t ser_readdata64(Stream &s)
Definition: serialize.h:119
void ser_writedata8(Stream &s, uint8_t obj)
Definition: serialize.h:60
uint64_t ReadCompactSize(Stream &is, bool range_check=true)
Decode a CompactSize-encoded variable-length integer.
Definition: serialize.h:282
uint32_t ser_readdata32(Stream &s)
Definition: serialize.h:107
uint16_t ser_readdata16be(Stream &s)
Definition: serialize.h:101
void ser_writedata64(Stream &s, uint64_t obj)
Definition: serialize.h:84
uint32_t ser_readdata32be(Stream &s)
Definition: serialize.h:113
void WriteCompactSize(CSizeComputer &os, uint64_t nSize)
Definition: serialize.h:1074
uint64_t SipHashUint256Extra(uint64_t k0, uint64_t k1, const uint256 &val, uint32_t extra)
Definition: siphash.cpp:134
uint64_t SipHashUint256(uint64_t k0, uint64_t k1, const uint256 &val)
Optimized SipHash-2-4 implementation for uint256.
Definition: siphash.cpp:94
std::string ToLower(const std::string &str)
Returns the lowercase equivalent of the given string.
signed char HexDigit(char c)
std::string ToUpper(const std::string &str)
Returns the uppercase equivalent of the given string.
constexpr bool IsDigit(char c)
Tests if the given character is a decimal digit.
Definition: strencodings.h:105
constexpr bool IsSpace(char c) noexcept
Tests if the given character is a whitespace character.
Definition: strencodings.h:121
std::string ToString(const T &t)
Locale-independent version of std::to_string.
Definition: string.h:87
Parameters that influence chain consensus.
Definition: params.h:70
bool IsSwitchChar(char c)
Definition: system.h:124
bool AdditionOverflow(const T i, const T j) noexcept
Definition: util.h:195
bool MultiplicationOverflow(const T i, const T j) noexcept
Definition: util.h:172
struct timeval MillisToTimeval(int64_t nTimeout)
Convert milliseconds to a struct timeval for e.g.
Definition: time.cpp:172
std::string FormatISO8601Date(int64_t nTime)
Definition: time.cpp:145
std::string FormatISO8601DateTime(int64_t nTime)
ISO 8601 formatting is preferred.
Definition: time.cpp:132
constexpr int64_t count_seconds(std::chrono::seconds t)
Helper to count the seconds of a duration.
Definition: time.h:29
uint256 uint256S(const char *str)
Definition: uint256.h:137
assert(!tx.IsCoinBase())
static const int INIT_PROTO_VERSION
initial proto version, to be increased after version/verack negotiation
Definition: version.h:15