veriblock-pop-cpp
C++11 Libraries for leveraging VeriBlock Proof-Of-Proof blockchain technology.
serde.hpp
1// Copyright (c) 2019-2022 Xenios SEZC
2// https://www.veriblock.org
3// Distributed under the MIT software license, see the accompanying
4// file LICENSE or http://www.opensource.org/licenses/mit-license.php.
5
6#ifndef ALT_INTEGRATION_VERIBLOCK_SERDE_HPP
7#define ALT_INTEGRATION_VERIBLOCK_SERDE_HPP
8
9#include <functional>
10#include <iterator>
11#include <stdexcept>
12#include <vector>
13
14#include "consts.hpp"
15#include "entities/network_byte_pair.hpp"
16#include "read_stream.hpp"
17#include "slice.hpp"
18#include "strutil.hpp"
19#include "write_stream.hpp"
20
25namespace altintegration {
26
27struct AltChainParams;
28
38bool checkRange(uint64_t num,
39 uint64_t min,
40 uint64_t max,
41 ValidationState& state);
42
49std::vector<uint8_t> trimmedArray(int64_t input);
50
56template <typename T,
57 typename = typename std::enable_if<std::is_integral<T>::value>::type>
58std::vector<uint8_t> fixedArray(T input) {
59 WriteStream inputStream;
60 inputStream.writeBE(input);
61 return inputStream.data();
62}
63
77 ValidationState& state,
78 uint64_t minLen,
79 uint64_t maxLen);
80
94 ValidationState& state,
95 uint64_t minLen,
96 uint64_t maxLen);
97
99template <typename Container,
100 typename = typename std::enable_if<
101 sizeof(typename Container::value_type) == 1>::type>
103 Container& out,
104 ValidationState& state,
105 uint64_t minLen,
106 uint64_t maxLen) {
107 uint8_t length = 0;
108 if (!stream.readBE<uint8_t>(length, state)) {
109 return state.Invalid("readsingle-bad-length");
110 }
111 if (!checkRange(length, minLen, maxLen, state)) {
112 return state.Invalid("readsingle-bad-range");
113 }
114 out.resize(length);
115 return stream.read(length, out.data(), state);
116}
117
128template <typename T,
129 typename = typename std::enable_if<std::is_integral<T>::value>::type>
130bool readSingleBEValue(ReadStream& stream, T& out, ValidationState& state) {
132 if (!readSingleByteLenValue(stream, data, state, 0, sizeof(T))) {
133 return state.Invalid("readsinglebe-bad-data");
134 }
135 ReadStream dataStream(data);
136 return dataStream.readBE<T>(out, state, data.size());
137}
138
148
157void writeSingleBEValue(WriteStream& stream, int64_t value);
158
167template <typename T,
168 typename = typename std::enable_if<std::is_integral<T>::value>::type>
169void writeSingleFixedBEValue(WriteStream& stream, T value) {
170 WriteStream dataStream;
171 dataStream.writeBE<T>(value);
172 writeSingleByteLenValue(stream, dataStream.data());
173}
174
184
186size_t singleByteLenValueSize(Slice<const uint8_t> value);
187
189size_t singleByteLenValueSize(size_t valueSize);
190
192size_t singleBEValueSize(int64_t value);
193
195template <typename T,
196 typename = typename std::enable_if<std::is_integral<T>::value>::type>
197size_t singleFixedBEValueSize(T value) {
198 WriteStream dataStream;
199 dataStream.writeBE<T>(value);
200 return singleByteLenValueSize(dataStream.data());
201}
202
204size_t varLenValueSize(Slice<const uint8_t> value);
205
207size_t varLenValueSize(size_t valueSize);
208
218
229 TxType type,
230 NetworkBytePair& out,
231 ValidationState& state);
232
239void writeNetworkByte(WriteStream& stream, NetworkBytePair networkOrType);
240
242size_t networkByteSize(NetworkBytePair networkOrType);
243
255template <typename Container>
257 Container& out,
258 ValidationState& state,
259 size_t min,
260 size_t max,
261 std::function<bool(ReadStream&,
262 typename Container::value_type&,
263 ValidationState&)> readFunc) {
264 int32_t count = 0;
265 if (!readSingleBEValue<int32_t>(stream, count, state)) {
266 return state.Invalid("readarray-bad-count");
267 }
268 if (!checkRange(count, min, max, state)) {
269 return state.Invalid("readarray-bad-range");
270 }
271
272 for (size_t i = 0; i < (size_t)count; i++) {
273 typename Container::value_type item;
274 if (!readFunc(stream, item, state)) {
275 return state.Invalid("readarray-bad-item", i);
276 }
277 if (out.insert(item).second == false) {
278 return state.Invalid("readarray-duplicate-item", i);
279 }
280 }
281
282 return true;
283}
284
295template <typename Container>
297 Container& out,
298 ValidationState& state,
299 std::function<bool(Container&,
300 ReadStream&,
301 typename Container::value_type&,
302 ValidationState&)> readFunc) {
303 int32_t max = std::numeric_limits<int32_t>::max();
304 return readContainer(stream, out, state, 0, max, readFunc);
305}
306
318template <typename T>
320 ReadStream& stream,
321 std::vector<T>& out,
322 ValidationState& state,
323 size_t min,
324 size_t max,
325 std::function<bool(ReadStream&, T&, ValidationState&)> readFunc) {
326 int32_t count = 0;
327 if (!readSingleBEValue<int32_t>(stream, count, state)) {
328 return state.Invalid("readarray-bad-count");
329 }
330 if (!checkRange(count, min, max, state)) {
331 return state.Invalid("readarray-bad-range");
332 }
333
334 out.reserve(count);
335
336 for (size_t i = 0; i < (size_t)count; i++) {
337 T item;
338 if (!readFunc(stream, item, state)) {
339 return state.Invalid("readarray-bad-item", i);
340 }
341 out.push_back(item);
342 }
343
344 return true;
345}
346
357template <typename T>
359 ReadStream& stream,
360 std::vector<T>& out,
361 ValidationState& state,
362 std::function<bool(ReadStream&, T&, ValidationState&)> readFunc) {
363 int32_t max = std::numeric_limits<int32_t>::max();
364 return readArrayOf<T>(stream, out, state, 0, max, readFunc);
365}
366
368template <typename Container>
369void writeContainer(
370 WriteStream& w,
371 const Container& t,
372 std::function<void(WriteStream&, const typename Container::value_type& t)>
373 f) {
374 writeSingleBEValue(w, (int64_t)t.size());
375 for (auto& v : t) {
376 f(w, v);
377 }
378}
379
381template <typename Container>
382size_t estimateContainerSize(
383 const Container& t,
384 std::function<size_t(const typename Container::value_type& t)> f) {
385 size_t size = 0;
386 size += singleBEValueSize((int64_t)t.size());
387 for (auto& v : t) {
388 size += f(v);
389 }
390 return size;
391}
392
394template <typename T>
395size_t estimateArraySizeOf(const std::vector<T>& t,
396 std::function<size_t(const T& t)> f) {
397 return estimateContainerSize<std::vector<T>>(t, f);
398}
399
401template <typename T>
403 T& out,
404 ValidationState& state) {
405 ReadStream stream(data);
406 return DeserializeFromVbkEncoding(stream, out, state);
407}
408
410template <typename T>
412 T& out,
413 ValidationState& state) {
414 ReadStream stream(data);
415 return DeserializeFromRaw(stream, out, state);
416}
417
419template <typename T>
420bool DeserializeFromHex(const std::string& hex,
421 T& out,
422 ValidationState& state) {
423 auto data = ParseHex(hex);
424 ReadStream stream(data);
425 return DeserializeFromVbkEncoding(stream, out, state);
426}
427
429template <typename T>
430bool DeserializeFromRawHex(const std::string& hex,
431 T& out,
432 ValidationState& state) {
433 auto data = ParseHex(hex);
434 ReadStream stream(data);
435 return DeserializeFromRaw(stream, out, state);
436}
437
439template <typename T>
440std::vector<uint8_t> SerializeToVbkEncoding(const T& obj) {
441 WriteStream w;
442 obj.toVbkEncoding(w);
443 return w.data();
444}
445
447template <typename T>
448std::vector<uint8_t> SerializeToRaw(const T& obj) {
449 WriteStream w;
450 obj.toRaw(w);
451 return w.data();
452}
453
455template <typename T>
456std::string SerializeToHex(const T& obj) {
457 return HexStr(SerializeToVbkEncoding<T>(obj));
458}
459
461template <typename T>
462std::string SerializeToRawHex(const T& obj) {
463 return HexStr(SerializeToRaw<T>(obj));
464}
465
468template <typename T>
469T AssertDeserializeFromRaw(std::vector<uint8_t> raw) {
470 T t;
471 ValidationState state;
472 bool result = DeserializeFromRaw(raw, t, state);
473 VBK_ASSERT_MSG(result, "Can't deserialize: %s", state.toString());
474 return t;
475}
476
479template <typename T>
481 T t;
482 ValidationState state;
483 bool result = DeserializeFromVbkEncoding(raw, t, state);
484 VBK_ASSERT_MSG(result, "Can't deserialize: %s", state.toString());
485 return t;
486}
487
490template <typename T>
491T AssertDeserializeFromHex(std::string hex) {
492 T t;
493 ValidationState state;
494 bool result = DeserializeFromHex(hex, t, state);
495 VBK_ASSERT_MSG(result, "Can't deserialize: %s", state.toString());
496 return t;
497}
498
501template <typename T>
502T AssertDeserializeFromRawHex(std::string hex) {
503 T t;
504 ValidationState state;
505 bool result = DeserializeFromRawHex(hex, t, state);
506 VBK_ASSERT_MSG(result, "Can`t deserialize: %s", state.toString());
507 return t;
508}
509
510} // namespace altintegration
511
512#endif // ALT_INTEGRATION_SERDE_HPP
Class that is used for storing validation state.
Binary writer that is useful for binary serialization.
All constants in alt-cpp.
Defines logging helpers.
Definition: block.hpp:14
bool checkRange(uint64_t num, uint64_t min, uint64_t max, ValidationState &state)
Checks if expression 'min' <= 'num' <= 'max' is true.
T AssertDeserializeFromRaw(std::vector< uint8_t > raw)
Deserialize from RAW encoding.
Definition: serde.hpp:469
bool DeserializeFromHex(const std::string &hex, T &out, ValidationState &state)
Deserialize from HEX VBK encoding.
Definition: serde.hpp:420
void writeSingleBEValue(WriteStream &stream, int64_t value)
Write single Big-Endian value to the stream.
bool DeserializeFromRaw(ReadStream &stream, AltBlock &out, ValidationState &state, const AltBlock::hash_t &=AltBlock::hash_t{})
This is an overloaded member function, provided for convenience. It differs from the above function o...
std::vector< uint8_t > SerializeToRaw(const T &obj)
Serialize to RAW encoding.
Definition: serde.hpp:448
void writeNetworkByte(WriteStream &stream, NetworkBytePair networkOrType)
Write optional network byte to the stream.
std::vector< uint8_t > fixedArray(T input)
Converts the input to the byte array.
Definition: serde.hpp:58
void writeSingleFixedBEValue(WriteStream &stream, T value)
Write single Big-Endian value to the stream.
Definition: serde.hpp:169
TxType
Veriblock transaction type.
Definition: consts.hpp:26
size_t estimateArraySizeOf(const std::vector< T > &t, std::function< size_t(const T &t)> f)
Estimate size of array in bytes.
Definition: serde.hpp:395
void writeSingleByteLenValue(WriteStream &stream, Slice< const uint8_t > value)
Write single byte length value, which consists of N bytes vector Appends 1 byte data length to the st...
T AssertDeserializeFromRawHex(std::string hex)
Deserialize from HEX RAW encoding.
Definition: serde.hpp:502
bool DeserializeFromVbkEncoding(ReadStream &stream, AltBlockAddon &out, ValidationState &state)
This is an overloaded member function, provided for convenience. It differs from the above function o...
std::string HexStr(const T itbegin, const T itend)
Convert bytes to hex.
Definition: strutil.hpp:44
std::vector< uint8_t > SerializeToVbkEncoding(const T &obj)
Serialize to VBK encoding.
Definition: serde.hpp:440
NetworkBytePair readNetworkByte(ReadStream &stream, TxType type)
Read optional network byte from the stream.
std::string SerializeToRawHex(const T &obj)
Serialize to HEX RAW encoding.
Definition: serde.hpp:462
T AssertDeserializeFromHex(std::string hex)
Deserialize from HEX VBK encoding.
Definition: serde.hpp:491
bool readSingleBEValue(ReadStream &stream, T &out, ValidationState &state)
Read single Big-Endian value from a stream.
Definition: serde.hpp:130
void writeVarLenValue(WriteStream &stream, Slice< const uint8_t > value)
Write variable length value, which consists of N bytes vector Appends up to 8 bytes data length to th...
bool readVarLenValue(ReadStream &stream, Slice< const uint8_t > &out, ValidationState &state, uint64_t minLen, uint64_t maxLen)
Read variable length value, which consists of [N=(4 bytes = size of slice) | N bytes slice] Size of s...
bool readSingleByteLenValue(ReadStream &stream, Slice< const uint8_t > &out, ValidationState &state, uint64_t minLen, uint64_t maxLen)
Read variable length value, which consists of [N=(1 byte = size of slice) | N bytes slice] Size of sl...
bool readSetOf(ReadStream &stream, Container &out, ValidationState &state, size_t min, size_t max, std::function< bool(ReadStream &, typename Container::value_type &, ValidationState &)> readFunc)
Reads set of entities of.
Definition: serde.hpp:256
std::vector< uint8_t > ParseHex(const char *psz)
Parse bytes from hex.
bool readArrayOf(ReadStream &stream, std::vector< T > &out, ValidationState &state, size_t min, size_t max, std::function< bool(ReadStream &, T &, ValidationState &)> readFunc)
Reads array of entities of type T.
Definition: serde.hpp:319
bool DeserializeFromRawHex(const std::string &hex, T &out, ValidationState &state)
Deserialize from HEX RAW encoding.
Definition: serde.hpp:430
std::string SerializeToHex(const T &obj)
Serialize to HEX VBK encoding.
Definition: serde.hpp:456
std::vector< uint8_t > trimmedArray(int64_t input)
Converts the input to the byte array and trims it's size to the lowest possible value.
T AssertDeserializeFromVbkEncoding(Slice< const uint8_t > raw)
Deserialize from VBK encoding.
Definition: serde.hpp:480
Stores pair of TxType and VBK network byte.
Binary reading stream, that is useful during binary deserialization.
Definition: read_stream.hpp:22
bool read(size_t size, uint8_t *out, ValidationState &state)
Read type T of 'size' bytes.
Non-owning contiguous array.
Definition: slice.hpp:22