mirror of
https://github.com/dashpay/dash.git
synced 2024-12-26 04:22:55 +01:00
Convert bitset serializationis to use formatters
This commit is contained in:
parent
64d4a48a09
commit
d60a6d1729
@ -54,20 +54,19 @@ public:
|
|||||||
bool VerifySizes(const Consensus::LLMQParams& params) const;
|
bool VerifySizes(const Consensus::LLMQParams& params) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ADD_SERIALIZE_METHODS
|
SERIALIZE_METHODS(CFinalCommitment, obj)
|
||||||
|
|
||||||
template<typename Stream, typename Operation>
|
|
||||||
inline void SerializationOp(Stream& s, Operation ser_action)
|
|
||||||
{
|
{
|
||||||
READWRITE(nVersion);
|
READWRITE(
|
||||||
READWRITE(llmqType);
|
obj.nVersion,
|
||||||
READWRITE(quorumHash);
|
obj.llmqType,
|
||||||
READWRITE(DYNBITSET(signers));
|
obj.quorumHash,
|
||||||
READWRITE(DYNBITSET(validMembers));
|
DYNBITSET(obj.signers),
|
||||||
READWRITE(quorumPublicKey);
|
DYNBITSET(obj.validMembers),
|
||||||
READWRITE(quorumVvecHash);
|
obj.quorumPublicKey,
|
||||||
READWRITE(quorumSig);
|
obj.quorumVvecHash,
|
||||||
READWRITE(membersSig);
|
obj.quorumSig,
|
||||||
|
obj.membersSig
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -95,17 +95,16 @@ public:
|
|||||||
CDKGComplaint() = default;
|
CDKGComplaint() = default;
|
||||||
explicit CDKGComplaint(const Consensus::LLMQParams& params);
|
explicit CDKGComplaint(const Consensus::LLMQParams& params);
|
||||||
|
|
||||||
ADD_SERIALIZE_METHODS
|
SERIALIZE_METHODS(CDKGComplaint, obj)
|
||||||
|
|
||||||
template<typename Stream, typename Operation>
|
|
||||||
inline void SerializationOp(Stream& s, Operation ser_action)
|
|
||||||
{
|
{
|
||||||
READWRITE(llmqType);
|
READWRITE(
|
||||||
READWRITE(quorumHash);
|
obj.llmqType,
|
||||||
READWRITE(proTxHash);
|
obj.quorumHash,
|
||||||
READWRITE(DYNBITSET(badMembers));
|
obj.proTxHash,
|
||||||
READWRITE(DYNBITSET(complainForMembers));
|
DYNBITSET(obj.badMembers),
|
||||||
READWRITE(sig);
|
DYNBITSET(obj.complainForMembers),
|
||||||
|
obj.sig
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint256 GetSignHash() const
|
uint256 GetSignHash() const
|
||||||
@ -174,19 +173,18 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ADD_SERIALIZE_METHODS
|
SERIALIZE_METHODS(CDKGPrematureCommitment, obj)
|
||||||
|
|
||||||
template<typename Stream, typename Operation>
|
|
||||||
inline void SerializationOp(Stream& s, Operation ser_action)
|
|
||||||
{
|
{
|
||||||
READWRITE(llmqType);
|
READWRITE(
|
||||||
READWRITE(quorumHash);
|
obj.llmqType,
|
||||||
READWRITE(proTxHash);
|
obj.quorumHash,
|
||||||
READWRITE(DYNBITSET(validMembers));
|
obj.proTxHash,
|
||||||
READWRITE(quorumPublicKey);
|
DYNBITSET(obj.validMembers),
|
||||||
READWRITE(quorumVvecHash);
|
obj.quorumPublicKey,
|
||||||
READWRITE(quorumSig);
|
obj.quorumVvecHash,
|
||||||
READWRITE(sig);
|
obj.quorumSig,
|
||||||
|
obj.sig
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint256 GetSignHash() const
|
uint256 GetSignHash() const
|
||||||
|
@ -98,16 +98,13 @@ public:
|
|||||||
std::vector<bool> inv;
|
std::vector<bool> inv;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ADD_SERIALIZE_METHODS
|
SERIALIZE_METHODS(CSigSharesInv, obj)
|
||||||
|
|
||||||
template<typename Stream, typename Operation>
|
|
||||||
inline void SerializationOp(Stream& s, Operation ser_action)
|
|
||||||
{
|
{
|
||||||
uint64_t invSize = inv.size();
|
uint64_t invSize = obj.inv.size();
|
||||||
|
READWRITE(VARINT(obj.sessionId), COMPACTSIZE(invSize));
|
||||||
READWRITE(VARINT(sessionId));
|
autobitset_t bitset = std::make_pair(obj.inv, (size_t)invSize);
|
||||||
READWRITE(COMPACTSIZE(invSize));
|
READWRITE(AUTOBITSET(bitset));
|
||||||
READWRITE(AUTOBITSET(inv, (size_t)invSize));
|
SER_READ(obj, obj.inv = bitset.first);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Init(size_t size);
|
void Init(size_t size);
|
||||||
|
286
src/serialize.h
286
src/serialize.h
@ -439,6 +439,143 @@ I ReadVarInt(Stream& is)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** TODO: describe FixedBitSet */
|
||||||
|
inline unsigned int GetSizeOfFixedBitSet(size_t size)
|
||||||
|
{
|
||||||
|
return (size + 7) / 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Stream>
|
||||||
|
void WriteFixedBitSet(Stream& s, const std::vector<bool>& vec, size_t size)
|
||||||
|
{
|
||||||
|
std::vector<unsigned char> vBytes((size + 7) / 8);
|
||||||
|
size_t ms = std::min(size, vec.size());
|
||||||
|
for (size_t p = 0; p < ms; p++)
|
||||||
|
vBytes[p / 8] |= vec[p] << (p % 8);
|
||||||
|
s.write((char*)vBytes.data(), vBytes.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Stream>
|
||||||
|
void ReadFixedBitSet(Stream& s, std::vector<bool>& vec, size_t size)
|
||||||
|
{
|
||||||
|
vec.resize(size);
|
||||||
|
|
||||||
|
std::vector<unsigned char> vBytes((size + 7) / 8);
|
||||||
|
s.read((char*)vBytes.data(), vBytes.size());
|
||||||
|
for (size_t p = 0; p < size; p++)
|
||||||
|
vec[p] = (vBytes[p / 8] & (1 << (p % 8))) != 0;
|
||||||
|
if (vBytes.size() * 8 != size) {
|
||||||
|
size_t rem = vBytes.size() * 8 - size;
|
||||||
|
uint8_t m = ~(uint8_t)(0xff >> rem);
|
||||||
|
if (vBytes[vBytes.size() - 1] & m) {
|
||||||
|
throw std::ios_base::failure("Out-of-range bits set");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores a fixed size bitset as a series of VarInts. Each VarInt is an offset from the last entry and the sum of the
|
||||||
|
* last entry and the offset gives an index into the bitset for a set bit. The series of VarInts ends with a 0.
|
||||||
|
*/
|
||||||
|
template<typename Stream>
|
||||||
|
void WriteFixedVarIntsBitSet(Stream& s, const std::vector<bool>& vec, size_t size)
|
||||||
|
{
|
||||||
|
int32_t last = -1;
|
||||||
|
for (int32_t i = 0; i < (int32_t)vec.size(); i++) {
|
||||||
|
if (vec[i]) {
|
||||||
|
WriteVarInt<Stream, VarIntMode::DEFAULT, uint32_t>(s, (uint32_t)(i - last));
|
||||||
|
last = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
WriteVarInt<Stream, VarIntMode::DEFAULT, uint32_t>(s, 0); // stopper
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Stream>
|
||||||
|
void ReadFixedVarIntsBitSet(Stream& s, std::vector<bool>& vec, size_t size)
|
||||||
|
{
|
||||||
|
vec.assign(size, false);
|
||||||
|
|
||||||
|
int32_t last = -1;
|
||||||
|
while(true) {
|
||||||
|
uint32_t offset = ReadVarInt<Stream, VarIntMode::DEFAULT, uint32_t>(s);
|
||||||
|
if (offset == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
int32_t idx = last + offset;
|
||||||
|
if (idx >= size) {
|
||||||
|
throw std::ios_base::failure("out of bounds index");
|
||||||
|
}
|
||||||
|
if (last != -1 && idx <= last) {
|
||||||
|
throw std::ios_base::failure("offset overflow");
|
||||||
|
}
|
||||||
|
vec[idx] = true;
|
||||||
|
last = idx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serializes either as a CFixedBitSet or CFixedVarIntsBitSet, depending on which would give a smaller size
|
||||||
|
*/
|
||||||
|
typedef std::pair<std::vector<bool>, size_t> autobitset_t;
|
||||||
|
|
||||||
|
struct CFixedBitSet
|
||||||
|
{
|
||||||
|
const std::vector<bool>& vec;
|
||||||
|
size_t size;
|
||||||
|
CFixedBitSet(const std::vector<bool>& vecIn, size_t sizeIn) : vec(vecIn), size(sizeIn) {}
|
||||||
|
template<typename Stream>
|
||||||
|
void Serialize(Stream& s) const { WriteFixedBitSet(s, vec, size); }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CFixedVarIntsBitSet
|
||||||
|
{
|
||||||
|
const std::vector<bool>& vec;
|
||||||
|
size_t size;
|
||||||
|
CFixedVarIntsBitSet(const std::vector<bool>& vecIn, size_t sizeIn) : vec(vecIn), size(sizeIn) {}
|
||||||
|
template<typename Stream>
|
||||||
|
void Serialize(Stream& s) const { WriteFixedVarIntsBitSet(s, vec, vec.size()); }
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Stream>
|
||||||
|
void WriteAutoBitSet(Stream& s, const autobitset_t& item)
|
||||||
|
{
|
||||||
|
auto& vec = item.first;
|
||||||
|
auto& size = item.second;
|
||||||
|
|
||||||
|
assert(vec.size() == size);
|
||||||
|
|
||||||
|
size_t size1 = ::GetSerializeSize(s, CFixedBitSet(vec, size));
|
||||||
|
size_t size2 = ::GetSerializeSize(s, CFixedVarIntsBitSet(vec, size));
|
||||||
|
|
||||||
|
assert(size1 == GetSizeOfFixedBitSet(size));
|
||||||
|
|
||||||
|
if (size1 < size2) {
|
||||||
|
ser_writedata8(s, 0);
|
||||||
|
WriteFixedBitSet(s, vec, vec.size());
|
||||||
|
} else {
|
||||||
|
ser_writedata8(s, 1);
|
||||||
|
WriteFixedVarIntsBitSet(s, vec, vec.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Stream>
|
||||||
|
void ReadAutoBitSet(Stream& s, autobitset_t& item)
|
||||||
|
{
|
||||||
|
uint8_t isVarInts = ser_readdata8(s);
|
||||||
|
if (isVarInts != 0 && isVarInts != 1) {
|
||||||
|
throw std::ios_base::failure("invalid value for isVarInts byte");
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& vec = item.first;
|
||||||
|
auto& size = item.second;
|
||||||
|
|
||||||
|
if (!isVarInts) {
|
||||||
|
ReadFixedBitSet(s, vec, size);
|
||||||
|
} else {
|
||||||
|
ReadFixedVarIntsBitSet(s, vec, size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Simple wrapper class to serialize objects using a formatter; used by Using(). */
|
/** Simple wrapper class to serialize objects using a formatter; used by Using(). */
|
||||||
template<typename Formatter, typename T>
|
template<typename Formatter, typename T>
|
||||||
class Wrapper
|
class Wrapper
|
||||||
@ -465,167 +602,44 @@ public:
|
|||||||
template<typename Formatter, typename T>
|
template<typename Formatter, typename T>
|
||||||
static inline Wrapper<Formatter, T&> Using(T&& t) { return Wrapper<Formatter, T&>(t); }
|
static inline Wrapper<Formatter, T&> Using(T&& t) { return Wrapper<Formatter, T&>(t); }
|
||||||
|
|
||||||
#define FIXEDBITSET(obj, size) CFixedBitSet(REF(obj), (size))
|
#define DYNBITSET(obj) Using<DynamicBitSetFormatter>(obj)
|
||||||
#define DYNBITSET(obj) CDynamicBitSet(REF(obj))
|
#define AUTOBITSET(obj) Using<AutoBitSetFormatter>(obj)
|
||||||
#define FIXEDVARINTSBITSET(obj, size) CFixedVarIntsBitSet(REF(obj), (size))
|
|
||||||
#define AUTOBITSET(obj, size) CAutoBitSet(REF(obj), (size))
|
|
||||||
#define VARINT(obj, ...) Using<VarIntFormatter<__VA_ARGS__>>(obj)
|
#define VARINT(obj, ...) Using<VarIntFormatter<__VA_ARGS__>>(obj)
|
||||||
#define COMPACTSIZE(obj) Using<CompactSizeFormatter>(obj)
|
#define COMPACTSIZE(obj) Using<CompactSizeFormatter>(obj)
|
||||||
#define LIMITED_STRING(obj,n) Using<LimitedStringFormatter<n>>(obj)
|
#define LIMITED_STRING(obj,n) Using<LimitedStringFormatter<n>>(obj)
|
||||||
|
|
||||||
class CFixedBitSet
|
/** TODO: describe DynamicBitSet */
|
||||||
|
struct DynamicBitSetFormatter
|
||||||
{
|
{
|
||||||
protected:
|
|
||||||
std::vector<bool>& vec;
|
|
||||||
size_t size;
|
|
||||||
|
|
||||||
public:
|
|
||||||
CFixedBitSet(std::vector<bool>& vecIn, size_t sizeIn) : vec(vecIn), size(sizeIn) {}
|
|
||||||
|
|
||||||
template<typename Stream>
|
template<typename Stream>
|
||||||
void Serialize(Stream& s) const
|
void Ser(Stream& s, const std::vector<bool>& vec) const
|
||||||
{
|
|
||||||
std::vector<unsigned char> vBytes((size + 7) / 8);
|
|
||||||
size_t ms = std::min(size, vec.size());
|
|
||||||
for (size_t p = 0; p < ms; p++)
|
|
||||||
vBytes[p / 8] |= vec[p] << (p % 8);
|
|
||||||
s.write((char*)vBytes.data(), vBytes.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Stream>
|
|
||||||
void Unserialize(Stream& s)
|
|
||||||
{
|
|
||||||
vec.resize(size);
|
|
||||||
|
|
||||||
std::vector<unsigned char> vBytes((size + 7) / 8);
|
|
||||||
s.read((char*)vBytes.data(), vBytes.size());
|
|
||||||
for (size_t p = 0; p < size; p++)
|
|
||||||
vec[p] = (vBytes[p / 8] & (1 << (p % 8))) != 0;
|
|
||||||
if (vBytes.size() * 8 != size) {
|
|
||||||
size_t rem = vBytes.size() * 8 - size;
|
|
||||||
uint8_t m = ~(uint8_t)(0xff >> rem);
|
|
||||||
if (vBytes[vBytes.size() - 1] & m) {
|
|
||||||
throw std::ios_base::failure("Out-of-range bits set");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class CDynamicBitSet
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
std::vector<bool>& vec;
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit CDynamicBitSet(std::vector<bool>& vecIn) : vec(vecIn) {}
|
|
||||||
|
|
||||||
template<typename Stream>
|
|
||||||
void Serialize(Stream& s) const
|
|
||||||
{
|
{
|
||||||
WriteCompactSize(s, vec.size());
|
WriteCompactSize(s, vec.size());
|
||||||
CFixedBitSet(REF(vec), vec.size()).Serialize(s);
|
WriteFixedBitSet(s, vec, vec.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Stream>
|
template<typename Stream>
|
||||||
void Unserialize(Stream& s)
|
void Unser(Stream& s, std::vector<bool>& vec)
|
||||||
{
|
{
|
||||||
vec.resize(ReadCompactSize(s));
|
ReadFixedBitSet(s, vec, ReadCompactSize(s));
|
||||||
CFixedBitSet(vec, vec.size()).Unserialize(s);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Stores a fixed size bitset as a series of VarInts. Each VarInt is an offset from the last entry and the sum of the
|
|
||||||
* last entry and the offset gives an index into the bitset for a set bit. The series of VarInts ends with a 0.
|
|
||||||
*/
|
|
||||||
class CFixedVarIntsBitSet
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
std::vector<bool>& vec;
|
|
||||||
size_t size;
|
|
||||||
|
|
||||||
public:
|
|
||||||
CFixedVarIntsBitSet(std::vector<bool>& vecIn, size_t sizeIn) : vec(vecIn), size(sizeIn) {}
|
|
||||||
|
|
||||||
template<typename Stream>
|
|
||||||
void Serialize(Stream& s) const
|
|
||||||
{
|
|
||||||
int32_t last = -1;
|
|
||||||
for (int32_t i = 0; i < (int32_t)vec.size(); i++) {
|
|
||||||
if (vec[i]) {
|
|
||||||
WriteVarInt<Stream, VarIntMode::DEFAULT, uint32_t>(s, (uint32_t)(i - last));
|
|
||||||
last = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
WriteVarInt<Stream, VarIntMode::DEFAULT, uint32_t>(s, 0); // stopper
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Stream>
|
|
||||||
void Unserialize(Stream& s)
|
|
||||||
{
|
|
||||||
vec.assign(size, false);
|
|
||||||
|
|
||||||
int32_t last = -1;
|
|
||||||
while(true) {
|
|
||||||
uint32_t offset = ReadVarInt<Stream, VarIntMode::DEFAULT, uint32_t>(s);
|
|
||||||
if (offset == 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
int32_t idx = last + offset;
|
|
||||||
if (idx >= size) {
|
|
||||||
throw std::ios_base::failure("out of bounds index");
|
|
||||||
}
|
|
||||||
if (last != -1 && idx <= last) {
|
|
||||||
throw std::ios_base::failure("offset overflow");
|
|
||||||
}
|
|
||||||
vec[idx] = true;
|
|
||||||
last = idx;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Serializes either as a CFixedBitSet or CFixedVarIntsBitSet, depending on which would give a smaller size
|
* Serializes either as a CFixedBitSet or CFixedVarIntsBitSet, depending on which would give a smaller size
|
||||||
*/
|
*/
|
||||||
class CAutoBitSet
|
struct AutoBitSetFormatter
|
||||||
{
|
{
|
||||||
protected:
|
|
||||||
std::vector<bool>& vec;
|
|
||||||
size_t size;
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit CAutoBitSet(std::vector<bool>& vecIn, size_t sizeIn) : vec(vecIn), size(sizeIn) {}
|
|
||||||
|
|
||||||
template<typename Stream>
|
template<typename Stream>
|
||||||
void Serialize(Stream& s) const
|
void Ser(Stream& s, const autobitset_t& item) const
|
||||||
{
|
{
|
||||||
assert(vec.size() == size);
|
WriteAutoBitSet(s, item);
|
||||||
|
|
||||||
size_t size1 = ::GetSerializeSize(s, CFixedBitSet(vec, size));
|
|
||||||
size_t size2 = ::GetSerializeSize(s, CFixedVarIntsBitSet(vec, size));
|
|
||||||
|
|
||||||
if (size1 < size2) {
|
|
||||||
ser_writedata8(s, 0);
|
|
||||||
s << FIXEDBITSET(vec, vec.size());
|
|
||||||
} else {
|
|
||||||
ser_writedata8(s, 1);
|
|
||||||
s << FIXEDVARINTSBITSET(vec, vec.size());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Stream>
|
template<typename Stream>
|
||||||
void Unserialize(Stream& s)
|
void Unser(Stream& s, autobitset_t& item)
|
||||||
{
|
{
|
||||||
uint8_t isVarInts = ser_readdata8(s);
|
ReadAutoBitSet(s, item);
|
||||||
if (isVarInts != 0 && isVarInts != 1) {
|
|
||||||
throw std::ios_base::failure("invalid value for isVarInts byte");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isVarInts) {
|
|
||||||
s >> FIXEDBITSET(vec, size);
|
|
||||||
} else {
|
|
||||||
s >> FIXEDVARINTSBITSET(vec, size);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user