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
This commit is contained in:
Pieter Wuille 2018-03-15 16:48:42 -07:00
commit 7be9a9a570
No known key found for this signature in database
GPG key ID: A636E97631F767E0
10 changed files with 30 additions and 56 deletions

View file

@ -90,11 +90,11 @@ public:
while (txn.size() < txn_size) { while (txn.size() < txn_size) {
txn.resize(std::min((uint64_t)(1000 + txn.size()), txn_size)); txn.resize(std::min((uint64_t)(1000 + txn.size()), txn_size));
for (; i < txn.size(); i++) for (; i < txn.size(); i++)
READWRITE(REF(TransactionCompressor(txn[i]))); READWRITE(TransactionCompressor(txn[i]));
} }
} else { } else {
for (size_t i = 0; i < txn.size(); i++) 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<uint16_t>::max()) if (idx > std::numeric_limits<uint16_t>::max())
throw std::ios_base::failure("index overflowed 16-bits"); throw std::ios_base::failure("index overflowed 16-bits");
index = idx; index = idx;
READWRITE(REF(TransactionCompressor(tx))); READWRITE(TransactionCompressor(tx));
} }
}; };

View file

@ -69,7 +69,7 @@ public:
::Unserialize(s, VARINT(code)); ::Unserialize(s, VARINT(code));
nHeight = code >> 1; nHeight = code >> 1;
fCoinBase = code & 1; fCoinBase = code & 1;
::Unserialize(s, REF(CTxOutCompressor(out))); ::Unserialize(s, CTxOutCompressor(out));
} }
bool IsSpent() const { bool IsSpent() const {

View file

@ -73,7 +73,7 @@ public:
s >> VARINT(nSize); s >> VARINT(nSize);
if (nSize < nSpecialScripts) { if (nSize < nSpecialScripts) {
std::vector<unsigned char> vch(GetSpecialSize(nSize), 0x00); std::vector<unsigned char> vch(GetSpecialSize(nSize), 0x00);
s >> REF(CFlatData(vch)); s >> CFlatData(vch);
Decompress(nSize, vch); Decompress(nSize, vch);
return; return;
} }
@ -84,7 +84,7 @@ public:
s.ignore(nSize); s.ignore(nSize);
} else { } else {
script.resize(nSize); script.resize(nSize);
s >> REF(CFlatData(script)); s >> CFlatData(script);
} }
} }
}; };

View file

@ -173,7 +173,7 @@ public:
} }
template<typename T> template<typename T>
CHashVerifier<Source>& operator>>(T& obj) CHashVerifier<Source>& operator>>(T&& obj)
{ {
// Unserialize from this stream // Unserialize from this stream
::Unserialize(*this, obj); ::Unserialize(*this, obj);

View file

@ -40,7 +40,7 @@ public:
} }
template<typename T> template<typename T>
TxInputStream& operator>>(T& obj) TxInputStream& operator>>(T&& obj)
{ {
::Unserialize(*this, obj); ::Unserialize(*this, obj);
return *this; return *this;

View file

@ -148,8 +148,7 @@ enum
SER_GETHASH = (1 << 2), SER_GETHASH = (1 << 2),
}; };
#define READWRITE(obj) (::SerReadWrite(s, (obj), ser_action)) #define READWRITE(...) (::SerReadWriteMany(s, ser_action, __VA_ARGS__))
#define READWRITEMANY(...) (::SerReadWriteMany(s, ser_action, __VA_ARGS__))
/** /**
* Implement three methods for serializable objects. These are actually wrappers over * Implement three methods for serializable objects. These are actually wrappers over
@ -351,10 +350,10 @@ I ReadVarInt(Stream& is)
} }
} }
#define FLATDATA(obj) REF(CFlatData((char*)&(obj), (char*)&(obj) + sizeof(obj))) #define FLATDATA(obj) CFlatData((char*)&(obj), (char*)&(obj) + sizeof(obj))
#define VARINT(obj) REF(WrapVarInt(REF(obj))) #define VARINT(obj) WrapVarInt(REF(obj))
#define COMPACTSIZE(obj) REF(CCompactSize(REF(obj))) #define COMPACTSIZE(obj) CCompactSize(REF(obj))
#define LIMITED_STRING(obj,n) REF(LimitedString< n >(REF(obj))) #define LIMITED_STRING(obj,n) LimitedString< n >(REF(obj))
/** /**
* Wrapper for serializing arrays and POD. * Wrapper for serializing arrays and POD.
@ -539,7 +538,7 @@ inline void Serialize(Stream& os, const T& a)
} }
template<typename Stream, typename T> template<typename Stream, typename T>
inline void Unserialize(Stream& is, T& a) inline void Unserialize(Stream& is, T&& a)
{ {
a.Unserialize(is); a.Unserialize(is);
} }
@ -825,19 +824,6 @@ struct CSerActionUnserialize
constexpr bool ForRead() const { return true; } constexpr bool ForRead() const { return true; }
}; };
template<typename Stream, typename T>
inline void SerReadWrite(Stream& s, const T& obj, CSerActionSerialize ser_action)
{
::Serialize(s, obj);
}
template<typename Stream, typename T>
inline void SerReadWrite(Stream& s, T& obj, CSerActionUnserialize ser_action)
{
::Unserialize(s, obj);
}
@ -897,17 +883,11 @@ void SerializeMany(Stream& s)
{ {
} }
template<typename Stream, typename Arg>
void SerializeMany(Stream& s, Arg&& arg)
{
::Serialize(s, std::forward<Arg>(arg));
}
template<typename Stream, typename Arg, typename... Args> template<typename Stream, typename Arg, typename... Args>
void SerializeMany(Stream& s, Arg&& arg, Args&&... args) void SerializeMany(Stream& s, const Arg& arg, const Args&... args)
{ {
::Serialize(s, std::forward<Arg>(arg)); ::Serialize(s, arg);
::SerializeMany(s, std::forward<Args>(args)...); ::SerializeMany(s, args...);
} }
template<typename Stream> template<typename Stream>
@ -915,27 +895,21 @@ inline void UnserializeMany(Stream& s)
{ {
} }
template<typename Stream, typename Arg>
inline void UnserializeMany(Stream& s, Arg& arg)
{
::Unserialize(s, arg);
}
template<typename Stream, typename Arg, typename... Args> template<typename Stream, typename Arg, typename... Args>
inline void UnserializeMany(Stream& s, Arg& arg, Args&... args) inline void UnserializeMany(Stream& s, Arg&& arg, Args&&... args)
{ {
::Unserialize(s, arg); ::Unserialize(s, arg);
::UnserializeMany(s, args...); ::UnserializeMany(s, args...);
} }
template<typename Stream, typename... Args> template<typename Stream, typename... Args>
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>(args)...); ::SerializeMany(s, args...);
} }
template<typename Stream, typename... Args> template<typename Stream, typename... Args>
inline void SerReadWriteMany(Stream& s, CSerActionUnserialize ser_action, Args&... args) inline void SerReadWriteMany(Stream& s, CSerActionUnserialize ser_action, Args&&... args)
{ {
::UnserializeMany(s, args...); ::UnserializeMany(s, args...);
} }

View file

@ -42,7 +42,7 @@ public:
} }
template<typename T> template<typename T>
OverrideStream<Stream>& operator>>(T& obj) OverrideStream<Stream>& operator>>(T&& obj)
{ {
// Unserialize from this stream // Unserialize from this stream
::Unserialize(*this, obj); ::Unserialize(*this, obj);
@ -399,7 +399,7 @@ public:
} }
template<typename T> template<typename T>
CDataStream& operator>>(T& obj) CDataStream& operator>>(T&& obj)
{ {
// Unserialize from this stream // Unserialize from this stream
::Unserialize(*this, obj); ::Unserialize(*this, obj);
@ -543,7 +543,7 @@ public:
} }
template<typename T> template<typename T>
CAutoFile& operator>>(T& obj) CAutoFile& operator>>(T&& obj)
{ {
// Unserialize from this stream // Unserialize from this stream
if (!file) if (!file)
@ -686,7 +686,7 @@ public:
} }
template<typename T> template<typename T>
CBufferedFile& operator>>(T& obj) { CBufferedFile& operator>>(T&& obj) {
// Unserialize from this stream // Unserialize from this stream
::Unserialize(*this, obj); ::Unserialize(*this, obj);
return (*this); return (*this);

View file

@ -53,7 +53,7 @@ public:
template <typename Stream, typename Operation> template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action) { inline void SerializationOp(Stream& s, Operation ser_action) {
READWRITEMANY(intval, boolval, stringval, FLATDATA(charstrval), txval); READWRITE(intval, boolval, stringval, FLATDATA(charstrval), txval);
} }
}; };

View file

@ -348,7 +348,7 @@ public:
vout.assign(vAvail.size(), CTxOut()); vout.assign(vAvail.size(), CTxOut());
for (unsigned int i = 0; i < vAvail.size(); i++) { for (unsigned int i = 0; i < vAvail.size(); i++) {
if (vAvail[i]) if (vAvail[i])
::Unserialize(s, REF(CTxOutCompressor(vout[i]))); ::Unserialize(s, CTxOutCompressor(vout[i]));
} }
// coinbase height // coinbase height
::Unserialize(s, VARINT(nHeight)); ::Unserialize(s, VARINT(nHeight));

View file

@ -54,7 +54,7 @@ public:
int nVersionDummy; int nVersionDummy;
::Unserialize(s, VARINT(nVersionDummy)); ::Unserialize(s, VARINT(nVersionDummy));
} }
::Unserialize(s, REF(CTxOutCompressor(REF(txout->out)))); ::Unserialize(s, CTxOutCompressor(REF(txout->out)));
} }
explicit TxInUndoDeserializer(Coin* coin) : txout(coin) {} explicit TxInUndoDeserializer(Coin* coin) : txout(coin) {}
@ -76,7 +76,7 @@ public:
uint64_t count = vprevout.size(); uint64_t count = vprevout.size();
::Serialize(s, COMPACTSIZE(REF(count))); ::Serialize(s, COMPACTSIZE(REF(count)));
for (const auto& prevout : vprevout) { for (const auto& prevout : vprevout) {
::Serialize(s, REF(TxInUndoSerializer(&prevout))); ::Serialize(s, TxInUndoSerializer(&prevout));
} }
} }
@ -90,7 +90,7 @@ public:
} }
vprevout.resize(count); vprevout.resize(count);
for (auto& prevout : vprevout) { for (auto& prevout : vprevout) {
::Unserialize(s, REF(TxInUndoDeserializer(&prevout))); ::Unserialize(s, TxInUndoDeserializer(&prevout));
} }
} }
}; };