message: Support bypassing range check in ReadCompactSize
  This is needed when we want to encode an arbitrary number as CompactSize
  like node service flags, which is a bitmask and could be bigger than the
  usual size of an object.
diff: #include <prevector.h>
  #include <span.h>
  -static const unsigned int MAX_SIZE = 0x02000000;
  +/**
  + * The maximum size of a serialized object in bytes or number of elements
  + * (for eg vectors) when the size is encoded as CompactSize.
  + */
  +static constexpr uint64_t MAX_SIZE = 0x02000000;
  /** Maximum amount of memory (in bytes) to allocate at once when deserializing vectors. */
  static const unsigned int MAX_VECTOR_ALLOCATE = 5000000;
  @@ -306,8 +310,14 @@ void WriteCompactSize(Stream& os, uint64_t nSize)
  return;
  }
  +/**
  + * Decode a CompactSize-encoded variable-length integer.
  + *
  + * As these are primarily used to encode the size of vector-like serializations, by default a range
  + * check is performed. When used as a generic number encoding, range_check should be set to false.
  + */
  template<typename Stream>
  -uint64_t ReadCompactSize(Stream& is)
  +uint64_t ReadCompactSize(Stream& is, bool range_check = true)
  {
  uint8_t chSize = ser_readdata8(is);
  uint64_t nSizeRet = 0;
  @@ -333,8 +343,9 @@ uint64_t ReadCompactSize(Stream& is)
  if (nSizeRet < 0x100000000ULL)
  throw std::ios_base::failure("non-canonical ReadCompactSize()");
  }
  - if (nSizeRet > (uint64_t)MAX_SIZE)
  + if (range_check && nSizeRet > MAX_SIZE) {
  throw std::ios_base::failure("ReadCompactSize(): size too large");
  + }
  return nSizeRet;
  }
  @@ -468,7 +479,7 @@ static inline Wrapper<Formatter, T&> Using(T&& t) { return Wrapper<Formatter, T&
  #define VARINT_MODE(obj, mode) Using<VarIntFormatter<mode>>(obj)
  #define VARINT(obj) Using<VarIntFormatter<VarIntMode::DEFAULT>>(obj)
  -#define COMPACTSIZE(obj) Using<CompactSizeFormatter>(obj)
  +#define COMPACTSIZE(obj) Using<CompactSizeFormatter<true>>(obj)
  #define LIMITED_STRING(obj,n) Using<LimitedStringFormatter<n>>(obj)
  /** Serialization wrapper class for integers in VarInt format. */
  @@ -531,12 +542,13 @@ struct CustomUintFormatter
  template<int Bytes> using BigEndianFormatter = CustomUintFormatter<Bytes, true>;
  /** Formatter for integers in CompactSize format. */
  +template<bool RangeCheck>
  struct CompactSizeFormatter
  {
  template<typename Stream, typename I>
  void Unser(Stream& s, I& v)
  {
  - uint64_t n = ReadCompactSize<Stream>(s);
  + uint64_t n = ReadCompactSize<Stream>(s, RangeCheck);
  if (n < std::numeric_limits<I>::min() || n > std::numeric_limits<I>::max()) {
  throw std::ios_base::failure("CompactSize exceeds limit of type");
  }
  