/ src / test / fuzz / integer.cpp
integer.cpp
  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>
 25  #include <test/fuzz/FuzzedDataProvider.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  
 45  void initialize_integer()
 46  {
 47      SelectParams(ChainType::REGTEST);
 48  }
 49  
 50  FUZZ_TARGET(integer, .init = initialize_integer)
 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  
 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      std::vector v256{u256, u256_min, u256_max};
 84      (void)ComputeMerkleRoot(std::move(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);
 92      (void)GetSpecialScriptSize(u32);
 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);
108      (void)memusage::DynamicUsage(u32);
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)PresaltedSipHasher(u64, u64)(u256);
122      (void)PresaltedSipHasher(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) {
131          assert(i32 == CScript::DecodeOP_N(CScript::EncodeOP_N(i32)));
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_writedata8(stream, u8);
240          const uint8_t deserialized_u8 = ser_readdata8(stream);
241          assert(u8 == deserialized_u8 && stream.empty());
242      }
243  
244      {
245          DataStream stream{};
246  
247          WriteCompactSize(stream, u64);
248          try {
249              const uint64_t deserialized_u64 = ReadCompactSize(stream);
250              assert(u64 == deserialized_u64 && stream.empty());
251          } catch (const std::ios_base::failure&) {
252          }
253      }
254  }