From ec710978010451bbf64775fb8f33428c874e7163 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Thu, 17 Dec 2020 05:07:07 +0300 Subject: [PATCH] Merge #12683: Fix more constness violations in serialization code 172f5fa738 Support deserializing into temporaries (Pieter Wuille) 2761bca997 Merge READWRITEMANY into READWRITE (Pieter Wuille) Pull request description: This is another fragment of improvements from #10785. The current serialization code does not support serializing/deserializing from/to temporaries (like `s >> CFlatData(script)`). As a result, there are many invocations of the `REF` macro which in addition to changing the reference type also changes the constness. This is unnecessary in C++11 as we can use rvalue references now instead. The first commit is an extra simplification we can make that removes the duplication of code between `READWRITE` and `READWRITEMANY` (and related functions). Tree-SHA512: babfa9cb268cc3bc39917e4f0a90e4651c33d85032161e16547a07f3b257b7ca7940e0cbfd69f09439d26fafbb1a6cf6359101043407e2c7aeececf7f20b6eed --- src/blockencodings.h | 6 ++-- src/coins.h | 2 +- src/compressor.h | 4 +-- src/hash.h | 2 +- src/script/dashconsensus.cpp | 2 +- src/serialize.h | 64 +++++++++++------------------------- src/streams.h | 6 ++-- src/test/serialize_tests.cpp | 2 +- src/txdb.cpp | 2 +- src/undo.h | 6 ++-- 10 files changed, 35 insertions(+), 61 deletions(-) diff --git a/src/blockencodings.h b/src/blockencodings.h index 4d09a75b38..61134c94b0 100644 --- a/src/blockencodings.h +++ b/src/blockencodings.h @@ -90,11 +90,11 @@ public: while (txn.size() < txn_size) { txn.resize(std::min((uint64_t)(1000 + txn.size()), txn_size)); for (; i < txn.size(); i++) - READWRITE(REF(TransactionCompressor(txn[i]))); + READWRITE(TransactionCompressor(txn[i])); } } else { for (size_t i = 0; i < txn.size(); i++) - READWRITE(REF(TransactionCompressor(txn[i]))); + READWRITE(TransactionCompressor(txn[i])); } } }; @@ -115,7 +115,7 @@ struct PrefilledTransaction { if (idx > std::numeric_limits::max()) throw std::ios_base::failure("index overflowed 16-bits"); index = idx; - READWRITE(REF(TransactionCompressor(tx))); + READWRITE(TransactionCompressor(tx)); } }; diff --git a/src/coins.h b/src/coins.h index 1885d6ae7a..bd472dacf7 100644 --- a/src/coins.h +++ b/src/coins.h @@ -69,7 +69,7 @@ public: ::Unserialize(s, VARINT(code)); nHeight = code >> 1; fCoinBase = code & 1; - ::Unserialize(s, REF(CTxOutCompressor(out))); + ::Unserialize(s, CTxOutCompressor(out)); } bool IsSpent() const { diff --git a/src/compressor.h b/src/compressor.h index 6ac7868ee8..3c083d002c 100644 --- a/src/compressor.h +++ b/src/compressor.h @@ -73,7 +73,7 @@ public: s >> VARINT(nSize); if (nSize < nSpecialScripts) { std::vector vch(GetSpecialSize(nSize), 0x00); - s >> REF(CFlatData(vch)); + s >> CFlatData(vch); Decompress(nSize, vch); return; } @@ -84,7 +84,7 @@ public: s.ignore(nSize); } else { script.resize(nSize); - s >> REF(CFlatData(script)); + s >> CFlatData(script); } } }; diff --git a/src/hash.h b/src/hash.h index 1ddf438678..44f3ff1f1d 100644 --- a/src/hash.h +++ b/src/hash.h @@ -241,7 +241,7 @@ public: } template - CHashVerifier& operator>>(T& obj) + CHashVerifier& operator>>(T&& obj) { // Unserialize from this stream ::Unserialize(*this, obj); diff --git a/src/script/dashconsensus.cpp b/src/script/dashconsensus.cpp index 6610fc0060..e60c010356 100644 --- a/src/script/dashconsensus.cpp +++ b/src/script/dashconsensus.cpp @@ -40,7 +40,7 @@ public: } template - TxInputStream& operator>>(T& obj) + TxInputStream& operator>>(T&& obj) { ::Unserialize(*this, obj); return *this; diff --git a/src/serialize.h b/src/serialize.h index 0ec8d46414..33fcf3ae3f 100644 --- a/src/serialize.h +++ b/src/serialize.h @@ -172,8 +172,7 @@ enum template X& ReadWriteAsHelper(X& x) { return x; } template const X& ReadWriteAsHelper(const X& x) { return x; } -#define READWRITE(obj) (::SerReadWrite(s, (obj), ser_action)) -#define READWRITEMANY(...) (::SerReadWriteMany(s, ser_action, __VA_ARGS__)) +#define READWRITE(...) (::SerReadWriteMany(s, ser_action, __VA_ARGS__)) #define READWRITEAS(type, obj) (::SerReadWriteMany(s, ser_action, ReadWriteAsHelper(obj))) /** @@ -386,14 +385,14 @@ I ReadVarInt(Stream& is) } } -#define FLATDATA(obj) REF(CFlatData((char*)&(obj), (char*)&(obj) + sizeof(obj))) -#define FIXEDBITSET(obj, size) REF(CFixedBitSet(REF(obj), (size))) -#define DYNBITSET(obj) REF(CDynamicBitSet(REF(obj))) -#define FIXEDVARINTSBITSET(obj, size) REF(CFixedVarIntsBitSet(REF(obj), (size))) -#define AUTOBITSET(obj, size) REF(CAutoBitSet(REF(obj), (size))) -#define VARINT(obj) REF(WrapVarInt(REF(obj))) -#define COMPACTSIZE(obj) REF(CCompactSize(REF(obj))) -#define LIMITED_STRING(obj,n) REF(LimitedString< n >(REF(obj))) +#define FLATDATA(obj) CFlatData((char*)&(obj), (char*)&(obj) + sizeof(obj)) +#define FIXEDBITSET(obj, size) CFixedBitSet(REF(obj), (size)) +#define DYNBITSET(obj) CDynamicBitSet(REF(obj)) +#define FIXEDVARINTSBITSET(obj, size) CFixedVarIntsBitSet(REF(obj), (size)) +#define AUTOBITSET(obj, size) CAutoBitSet(REF(obj), (size)) +#define VARINT(obj) WrapVarInt(REF(obj)) +#define COMPACTSIZE(obj) CCompactSize(REF(obj)) +#define LIMITED_STRING(obj,n) LimitedString< n >(REF(obj)) /** * Wrapper for serializing arrays and POD. @@ -747,8 +746,8 @@ inline void Serialize(Stream& os, const T& a) a.Serialize(os); } -template::value>::type* = nullptr> -inline void Unserialize(Stream& is, T& a) +template >::value>::type* = nullptr> +inline void Unserialize(Stream& is, T&& a) { a.Unserialize(is); } @@ -764,7 +763,7 @@ template struct is_serializable_enum; template struct is_serializable_enum : std::false_type {}; template::value>::type* = nullptr> -inline void Serialize(Stream& s, T a ) +inline void Serialize(Stream& s, const T& a ) { // If you ever get into this situation, it usaully means you forgot to declare is_serializable_enum for the desired enum type static_assert(is_serializable_enum::value, "Missing declararion of is_serializable_enum"); @@ -1184,19 +1183,6 @@ struct CSerActionUnserialize constexpr bool ForRead() const { return true; } }; -template -inline void SerReadWrite(Stream& s, const T& obj, CSerActionSerialize ser_action) -{ - ::Serialize(s, obj); -} - -template -inline void SerReadWrite(Stream& s, T& obj, CSerActionUnserialize ser_action) -{ - ::Unserialize(s, obj); -} - - @@ -1256,17 +1242,11 @@ void SerializeMany(Stream& s) { } -template -void SerializeMany(Stream& s, Arg&& arg) -{ - ::Serialize(s, std::forward(arg)); -} - template -void SerializeMany(Stream& s, Arg&& arg, Args&&... args) +void SerializeMany(Stream& s, const Arg& arg, const Args&... args) { - ::Serialize(s, std::forward(arg)); - ::SerializeMany(s, std::forward(args)...); + ::Serialize(s, arg); + ::SerializeMany(s, args...); } template @@ -1274,27 +1254,21 @@ inline void UnserializeMany(Stream& s) { } -template -inline void UnserializeMany(Stream& s, Arg& arg) -{ - ::Unserialize(s, arg); -} - template -inline void UnserializeMany(Stream& s, Arg& arg, Args&... args) +inline void UnserializeMany(Stream& s, Arg&& arg, Args&&... args) { ::Unserialize(s, arg); ::UnserializeMany(s, args...); } template -inline void SerReadWriteMany(Stream& s, CSerActionSerialize ser_action, Args&&... args) +inline void SerReadWriteMany(Stream& s, CSerActionSerialize ser_action, const Args&... args) { - ::SerializeMany(s, std::forward(args)...); + ::SerializeMany(s, args...); } template -inline void SerReadWriteMany(Stream& s, CSerActionUnserialize ser_action, Args&... args) +inline void SerReadWriteMany(Stream& s, CSerActionUnserialize ser_action, Args&&... args) { ::UnserializeMany(s, args...); } diff --git a/src/streams.h b/src/streams.h index 69c9747f82..21db4ba6dd 100644 --- a/src/streams.h +++ b/src/streams.h @@ -430,7 +430,7 @@ public: } template - CDataStream& operator>>(T& obj) + CDataStream& operator>>(T&& obj) { // Unserialize from this stream ::Unserialize(*this, obj); @@ -667,7 +667,7 @@ public: } template - CAutoFile& operator>>(T& obj) + CAutoFile& operator>>(T&& obj) { // Unserialize from this stream if (!file) @@ -810,7 +810,7 @@ public: } template - CBufferedFile& operator>>(T& obj) { + CBufferedFile& operator>>(T&& obj) { // Unserialize from this stream ::Unserialize(*this, obj); return (*this); diff --git a/src/test/serialize_tests.cpp b/src/test/serialize_tests.cpp index e3be2030db..3282ed9932 100644 --- a/src/test/serialize_tests.cpp +++ b/src/test/serialize_tests.cpp @@ -57,7 +57,7 @@ public: template inline void SerializationOp(Stream& s, Operation ser_action) { - READWRITEMANY(intval, boolval, stringval, charstrval, txval); + READWRITE(intval, boolval, stringval, charstrval, txval); } }; diff --git a/src/txdb.cpp b/src/txdb.cpp index 04f58cb8a1..1b9cac8caa 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -502,7 +502,7 @@ public: vout.assign(vAvail.size(), CTxOut()); for (unsigned int i = 0; i < vAvail.size(); i++) { if (vAvail[i]) - ::Unserialize(s, REF(CTxOutCompressor(vout[i]))); + ::Unserialize(s, CTxOutCompressor(vout[i])); } // coinbase height ::Unserialize(s, VARINT(nHeight)); diff --git a/src/undo.h b/src/undo.h index 0836315fee..c58db2c408 100644 --- a/src/undo.h +++ b/src/undo.h @@ -55,7 +55,7 @@ public: int nVersionDummy; ::Unserialize(s, VARINT(nVersionDummy)); } - ::Unserialize(s, REF(CTxOutCompressor(REF(txout->out)))); + ::Unserialize(s, CTxOutCompressor(REF(txout->out))); } explicit TxInUndoDeserializer(Coin* coin) : txout(coin) {} @@ -76,7 +76,7 @@ public: uint64_t count = vprevout.size(); ::Serialize(s, COMPACTSIZE(REF(count))); for (const auto& prevout : vprevout) { - ::Serialize(s, REF(TxInUndoSerializer(&prevout))); + ::Serialize(s, TxInUndoSerializer(&prevout)); } } @@ -90,7 +90,7 @@ public: } vprevout.resize(count); for (auto& prevout : vprevout) { - ::Unserialize(s, REF(TxInUndoDeserializer(&prevout))); + ::Unserialize(s, TxInUndoDeserializer(&prevout)); } } };