From 3d796f89962842e91e7d88e57c1d2d579f01052e Mon Sep 17 00:00:00 2001 From: Kamil Domanski Date: Wed, 20 Aug 2014 08:42:31 +0200 Subject: overhaul serialization code The implementation of each class' serialization/deserialization is no longer passed within a macro. The implementation now lies within a template of form: template inline static size_t SerializationOp(T thisPtr, Stream& s, Operation ser_action, int nType, int nVersion) { size_t nSerSize = 0; /* CODE */ return nSerSize; } In cases when codepath should depend on whether or not we are just deserializing (old fGetSize, fWrite, fRead flags) an additional clause can be used: bool fRead = boost::is_same(); The IMPLEMENT_SERIALIZE macro will now be a freestanding clause added within class' body (similiar to Qt's Q_OBJECT) to implement GetSerializeSize, Serialize and Unserialize. These are now wrappers around the "SerializationOp" template. --- src/core.h | 168 +++++++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 118 insertions(+), 50 deletions(-) (limited to 'src/core.h') diff --git a/src/core.h b/src/core.h index 126e1baa98..1caf9da6c0 100644 --- a/src/core.h +++ b/src/core.h @@ -30,7 +30,16 @@ public: COutPoint() { SetNull(); } COutPoint(uint256 hashIn, uint32_t nIn) { hash = hashIn; n = nIn; } - IMPLEMENT_SERIALIZE( READWRITE(FLATDATA(*this)); ) + + IMPLEMENT_SERIALIZE + + template + inline static size_t SerializationOp(T thisPtr, Stream& s, Operation ser_action, int nType, int nVersion) { + size_t nSerSize = 0; + READWRITE(FLATDATA(*thisPtr)); + return nSerSize; + } + void SetNull() { hash = 0; n = (uint32_t) -1; } bool IsNull() const { return (hash == 0 && n == (uint32_t) -1); } @@ -85,11 +94,15 @@ public: CTxIn(uint256 hashPrevTx, uint32_t nOut, CScript scriptSigIn=CScript(), uint32_t nSequenceIn=std::numeric_limits::max()); IMPLEMENT_SERIALIZE - ( - READWRITE(prevout); - READWRITE(scriptSig); - READWRITE(nSequence); - ) + + template + inline static size_t SerializationOp(T thisPtr, Stream& s, Operation ser_action, int nType, int nVersion) { + size_t nSerSize = 0; + READWRITE(thisPtr->prevout); + READWRITE(thisPtr->scriptSig); + READWRITE(thisPtr->nSequence); + return nSerSize; + } bool IsFinal() const { @@ -136,7 +149,14 @@ public: friend bool operator>=(const CFeeRate& a, const CFeeRate& b) { return a.nSatoshisPerK >= b.nSatoshisPerK; } std::string ToString() const; - IMPLEMENT_SERIALIZE( READWRITE(nSatoshisPerK); ) + IMPLEMENT_SERIALIZE + + template + inline static size_t SerializationOp(T thisPtr, Stream& s, Operation ser_action, int nType, int nVersion) { + size_t nSerSize = 0; + READWRITE(thisPtr->nSatoshisPerK); + return nSerSize; + } }; @@ -157,10 +177,14 @@ public: CTxOut(int64_t nValueIn, CScript scriptPubKeyIn); IMPLEMENT_SERIALIZE - ( - READWRITE(nValue); - READWRITE(scriptPubKey); - ) + + template + inline static size_t SerializationOp(T thisPtr, Stream& s, Operation ser_action, int nType, int nVersion) { + size_t nSerSize = 0; + READWRITE(thisPtr->nValue); + READWRITE(thisPtr->scriptPubKey); + return nSerSize; + } void SetNull() { @@ -237,15 +261,23 @@ public: CTransaction& operator=(const CTransaction& tx); - IMPLEMENT_SERIALIZE( - READWRITE(*const_cast(&this->nVersion)); - nVersion = this->nVersion; - READWRITE(*const_cast*>(&vin)); - READWRITE(*const_cast*>(&vout)); - READWRITE(*const_cast(&nLockTime)); + IMPLEMENT_SERIALIZE + + template + inline static size_t SerializationOp(T thisPtr, Stream& s, Operation ser_action, int nType, int nVersion) { + size_t nSerSize = 0; + bool fRead = boost::is_same(); + + READWRITE(*const_cast(&thisPtr->nVersion)); + nVersion = thisPtr->nVersion; + READWRITE(*const_cast*>(&thisPtr->vin)); + READWRITE(*const_cast*>(&thisPtr->vout)); + READWRITE(*const_cast(&thisPtr->nLockTime)); if (fRead) - UpdateHash(); - ) + thisPtr->UpdateHash(); + + return nSerSize; + } bool IsNull() const { return vin.empty() && vout.empty(); @@ -292,13 +324,20 @@ struct CMutableTransaction CMutableTransaction(); CMutableTransaction(const CTransaction& tx); - IMPLEMENT_SERIALIZE( - READWRITE(this->nVersion); - nVersion = this->nVersion; - READWRITE(vin); - READWRITE(vout); - READWRITE(nLockTime); - ) + IMPLEMENT_SERIALIZE + + template + inline static size_t SerializationOp(T thisPtr, Stream& s, Operation ser_action, int nType, int nVersion) { + size_t nSerSize = 0; + + READWRITE(thisPtr->nVersion); + nVersion = thisPtr->nVersion; + READWRITE(thisPtr->vin); + READWRITE(thisPtr->vout); + READWRITE(thisPtr->nLockTime); + + return nSerSize; + } /** Compute the hash of this CMutableTransaction. This is computed on the * fly, as opposed to GetHash() in CTransaction, which uses a cached result. @@ -318,18 +357,24 @@ public: CTxOutCompressor(CTxOut &txoutIn) : txout(txoutIn) { } - IMPLEMENT_SERIALIZE(({ + IMPLEMENT_SERIALIZE + + template + inline static size_t SerializationOp(T thisPtr, Stream& s, Operation ser_action, int nType, int nVersion) { + bool fRead = boost::is_same(); + size_t nSerSize = 0; if (!fRead) { - uint64_t nVal = CompressAmount(txout.nValue); + uint64_t nVal = CompressAmount(thisPtr->txout.nValue); READWRITE(VARINT(nVal)); } else { uint64_t nVal = 0; READWRITE(VARINT(nVal)); - txout.nValue = DecompressAmount(nVal); + thisPtr->txout.nValue = DecompressAmount(nVal); } - CScriptCompressor cscript(REF(txout.scriptPubKey)); + CScriptCompressor cscript(REF(thisPtr->txout.scriptPubKey)); READWRITE(cscript); - });) + return nSerSize; + } }; /** Undo information for a CTxIn @@ -382,9 +427,14 @@ public: // undo information for all txins std::vector vprevout; - IMPLEMENT_SERIALIZE( - READWRITE(vprevout); - ) + IMPLEMENT_SERIALIZE + + template + inline static size_t SerializationOp(T thisPtr, Stream& s, Operation ser_action, int nType, int nVersion) { + size_t nSerSize = 0; + READWRITE(thisPtr->vprevout); + return nSerSize; + } }; @@ -413,15 +463,21 @@ public: } IMPLEMENT_SERIALIZE - ( - READWRITE(this->nVersion); - nVersion = this->nVersion; - READWRITE(hashPrevBlock); - READWRITE(hashMerkleRoot); - READWRITE(nTime); - READWRITE(nBits); - READWRITE(nNonce); - ) + + template + inline static size_t SerializationOp(T thisPtr, Stream& s, Operation ser_action, int nType, int nVersion) { + size_t nSerSize = 0; + + READWRITE(thisPtr->nVersion); + nVersion = thisPtr->nVersion; + READWRITE(thisPtr->hashPrevBlock); + READWRITE(thisPtr->hashMerkleRoot); + READWRITE(thisPtr->nTime); + READWRITE(thisPtr->nBits); + READWRITE(thisPtr->nNonce); + + return nSerSize; + } void SetNull() { @@ -468,10 +524,16 @@ public: } IMPLEMENT_SERIALIZE - ( - READWRITE(*(CBlockHeader*)this); - READWRITE(vtx); - ) + + template + inline static size_t SerializationOp(T thisPtr, Stream& s, Operation ser_action, int nType, int nVersion) { + size_t nSerSize = 0; + + READWRITE(*(CBlockHeader*)thisPtr); + READWRITE(thisPtr->vtx); + + return nSerSize; + } void SetNull() { @@ -516,11 +578,17 @@ struct CBlockLocator } IMPLEMENT_SERIALIZE - ( + + template + inline static size_t SerializationOp(T thisPtr, Stream& s, Operation ser_action, int nType, int nVersion) { + size_t nSerSize = 0; + if (!(nType & SER_GETHASH)) READWRITE(nVersion); - READWRITE(vHave); - ) + READWRITE(thisPtr->vHave); + + return nSerSize; + } void SetNull() { -- cgit v1.2.3 From 84881f8c472cc67dc757686eb7dc3b495b13cab8 Mon Sep 17 00:00:00 2001 From: Kamil Domanski Date: Wed, 20 Aug 2014 22:44:38 +0200 Subject: rework overhauled serialization methods to non-static Thanks to Pieter Wuille for most of the work on this commit. I did not fixup the overhaul commit, because a rebase conflicted with "remove fields of ser_streamplaceholder". I prefer not to risk making a mistake while resolving it. --- src/core.h | 130 ++++++++++++++++++++++++++++++------------------------------- 1 file changed, 65 insertions(+), 65 deletions(-) (limited to 'src/core.h') diff --git a/src/core.h b/src/core.h index 1caf9da6c0..e56be1a4ec 100644 --- a/src/core.h +++ b/src/core.h @@ -31,12 +31,12 @@ public: COutPoint() { SetNull(); } COutPoint(uint256 hashIn, uint32_t nIn) { hash = hashIn; n = nIn; } - IMPLEMENT_SERIALIZE + IMPLEMENT_SERIALIZE; - template - inline static size_t SerializationOp(T thisPtr, Stream& s, Operation ser_action, int nType, int nVersion) { + template + inline size_t SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { size_t nSerSize = 0; - READWRITE(FLATDATA(*thisPtr)); + READWRITE(FLATDATA(*this)); return nSerSize; } @@ -93,14 +93,14 @@ public: explicit CTxIn(COutPoint prevoutIn, CScript scriptSigIn=CScript(), uint32_t nSequenceIn=std::numeric_limits::max()); CTxIn(uint256 hashPrevTx, uint32_t nOut, CScript scriptSigIn=CScript(), uint32_t nSequenceIn=std::numeric_limits::max()); - IMPLEMENT_SERIALIZE + IMPLEMENT_SERIALIZE; - template - inline static size_t SerializationOp(T thisPtr, Stream& s, Operation ser_action, int nType, int nVersion) { + template + inline size_t SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { size_t nSerSize = 0; - READWRITE(thisPtr->prevout); - READWRITE(thisPtr->scriptSig); - READWRITE(thisPtr->nSequence); + READWRITE(prevout); + READWRITE(scriptSig); + READWRITE(nSequence); return nSerSize; } @@ -149,12 +149,12 @@ public: friend bool operator>=(const CFeeRate& a, const CFeeRate& b) { return a.nSatoshisPerK >= b.nSatoshisPerK; } std::string ToString() const; - IMPLEMENT_SERIALIZE + IMPLEMENT_SERIALIZE; - template - inline static size_t SerializationOp(T thisPtr, Stream& s, Operation ser_action, int nType, int nVersion) { + template + inline size_t SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { size_t nSerSize = 0; - READWRITE(thisPtr->nSatoshisPerK); + READWRITE(nSatoshisPerK); return nSerSize; } }; @@ -176,13 +176,13 @@ public: CTxOut(int64_t nValueIn, CScript scriptPubKeyIn); - IMPLEMENT_SERIALIZE + IMPLEMENT_SERIALIZE; - template - inline static size_t SerializationOp(T thisPtr, Stream& s, Operation ser_action, int nType, int nVersion) { + template + inline size_t SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { size_t nSerSize = 0; - READWRITE(thisPtr->nValue); - READWRITE(thisPtr->scriptPubKey); + READWRITE(nValue); + READWRITE(scriptPubKey); return nSerSize; } @@ -261,20 +261,20 @@ public: CTransaction& operator=(const CTransaction& tx); - IMPLEMENT_SERIALIZE + IMPLEMENT_SERIALIZE; - template - inline static size_t SerializationOp(T thisPtr, Stream& s, Operation ser_action, int nType, int nVersion) { + template + inline size_t SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { size_t nSerSize = 0; bool fRead = boost::is_same(); - READWRITE(*const_cast(&thisPtr->nVersion)); - nVersion = thisPtr->nVersion; - READWRITE(*const_cast*>(&thisPtr->vin)); - READWRITE(*const_cast*>(&thisPtr->vout)); - READWRITE(*const_cast(&thisPtr->nLockTime)); + READWRITE(*const_cast(&this->nVersion)); + nVersion = this->nVersion; + READWRITE(*const_cast*>(&vin)); + READWRITE(*const_cast*>(&vout)); + READWRITE(*const_cast(&nLockTime)); if (fRead) - thisPtr->UpdateHash(); + UpdateHash(); return nSerSize; } @@ -324,17 +324,17 @@ struct CMutableTransaction CMutableTransaction(); CMutableTransaction(const CTransaction& tx); - IMPLEMENT_SERIALIZE + IMPLEMENT_SERIALIZE; - template - inline static size_t SerializationOp(T thisPtr, Stream& s, Operation ser_action, int nType, int nVersion) { + template + inline size_t SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { size_t nSerSize = 0; - READWRITE(thisPtr->nVersion); - nVersion = thisPtr->nVersion; - READWRITE(thisPtr->vin); - READWRITE(thisPtr->vout); - READWRITE(thisPtr->nLockTime); + READWRITE(this->nVersion); + nVersion = this->nVersion; + READWRITE(vin); + READWRITE(vout); + READWRITE(nLockTime); return nSerSize; } @@ -357,21 +357,21 @@ public: CTxOutCompressor(CTxOut &txoutIn) : txout(txoutIn) { } - IMPLEMENT_SERIALIZE + IMPLEMENT_SERIALIZE; - template - inline static size_t SerializationOp(T thisPtr, Stream& s, Operation ser_action, int nType, int nVersion) { + template + inline size_t SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { bool fRead = boost::is_same(); size_t nSerSize = 0; if (!fRead) { - uint64_t nVal = CompressAmount(thisPtr->txout.nValue); + uint64_t nVal = CompressAmount(txout.nValue); READWRITE(VARINT(nVal)); } else { uint64_t nVal = 0; READWRITE(VARINT(nVal)); - thisPtr->txout.nValue = DecompressAmount(nVal); + txout.nValue = DecompressAmount(nVal); } - CScriptCompressor cscript(REF(thisPtr->txout.scriptPubKey)); + CScriptCompressor cscript(REF(txout.scriptPubKey)); READWRITE(cscript); return nSerSize; } @@ -427,12 +427,12 @@ public: // undo information for all txins std::vector vprevout; - IMPLEMENT_SERIALIZE + IMPLEMENT_SERIALIZE; - template - inline static size_t SerializationOp(T thisPtr, Stream& s, Operation ser_action, int nType, int nVersion) { + template + inline size_t SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { size_t nSerSize = 0; - READWRITE(thisPtr->vprevout); + READWRITE(vprevout); return nSerSize; } }; @@ -462,19 +462,19 @@ public: SetNull(); } - IMPLEMENT_SERIALIZE + IMPLEMENT_SERIALIZE; - template - inline static size_t SerializationOp(T thisPtr, Stream& s, Operation ser_action, int nType, int nVersion) { + template + inline size_t SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { size_t nSerSize = 0; - READWRITE(thisPtr->nVersion); - nVersion = thisPtr->nVersion; - READWRITE(thisPtr->hashPrevBlock); - READWRITE(thisPtr->hashMerkleRoot); - READWRITE(thisPtr->nTime); - READWRITE(thisPtr->nBits); - READWRITE(thisPtr->nNonce); + READWRITE(this->nVersion); + nVersion = this->nVersion; + READWRITE(hashPrevBlock); + READWRITE(hashMerkleRoot); + READWRITE(nTime); + READWRITE(nBits); + READWRITE(nNonce); return nSerSize; } @@ -523,14 +523,14 @@ public: *((CBlockHeader*)this) = header; } - IMPLEMENT_SERIALIZE + IMPLEMENT_SERIALIZE; - template - inline static size_t SerializationOp(T thisPtr, Stream& s, Operation ser_action, int nType, int nVersion) { + template + inline size_t SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { size_t nSerSize = 0; - READWRITE(*(CBlockHeader*)thisPtr); - READWRITE(thisPtr->vtx); + READWRITE(*(CBlockHeader*)this); + READWRITE(vtx); return nSerSize; } @@ -577,15 +577,15 @@ struct CBlockLocator vHave = vHaveIn; } - IMPLEMENT_SERIALIZE + IMPLEMENT_SERIALIZE; - template - inline static size_t SerializationOp(T thisPtr, Stream& s, Operation ser_action, int nType, int nVersion) { + template + inline size_t SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { size_t nSerSize = 0; if (!(nType & SER_GETHASH)) READWRITE(nVersion); - READWRITE(thisPtr->vHave); + READWRITE(vHave); return nSerSize; } -- cgit v1.2.3 From 31e9a8384a77947f6777d035992f4734618ed206 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Thu, 21 Aug 2014 00:49:32 +0200 Subject: Use CSizeComputer to avoid counting sizes in SerializationOp --- src/core.h | 57 +++++++++++++-------------------------------------------- 1 file changed, 13 insertions(+), 44 deletions(-) (limited to 'src/core.h') diff --git a/src/core.h b/src/core.h index e56be1a4ec..486782e5b7 100644 --- a/src/core.h +++ b/src/core.h @@ -34,10 +34,8 @@ public: IMPLEMENT_SERIALIZE; template - inline size_t SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { - size_t nSerSize = 0; + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { READWRITE(FLATDATA(*this)); - return nSerSize; } void SetNull() { hash = 0; n = (uint32_t) -1; } @@ -96,12 +94,10 @@ public: IMPLEMENT_SERIALIZE; template - inline size_t SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { - size_t nSerSize = 0; + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { READWRITE(prevout); READWRITE(scriptSig); READWRITE(nSequence); - return nSerSize; } bool IsFinal() const @@ -152,10 +148,8 @@ public: IMPLEMENT_SERIALIZE; template - inline size_t SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { - size_t nSerSize = 0; + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { READWRITE(nSatoshisPerK); - return nSerSize; } }; @@ -179,11 +173,9 @@ public: IMPLEMENT_SERIALIZE; template - inline size_t SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { - size_t nSerSize = 0; + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { READWRITE(nValue); READWRITE(scriptPubKey); - return nSerSize; } void SetNull() @@ -264,9 +256,8 @@ public: IMPLEMENT_SERIALIZE; template - inline size_t SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { - size_t nSerSize = 0; - bool fRead = boost::is_same(); + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + bool fRead = ser_action.ForRead(); READWRITE(*const_cast(&this->nVersion)); nVersion = this->nVersion; @@ -275,8 +266,6 @@ public: READWRITE(*const_cast(&nLockTime)); if (fRead) UpdateHash(); - - return nSerSize; } bool IsNull() const { @@ -327,16 +316,12 @@ struct CMutableTransaction IMPLEMENT_SERIALIZE; template - inline size_t SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { - size_t nSerSize = 0; - + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { READWRITE(this->nVersion); nVersion = this->nVersion; READWRITE(vin); READWRITE(vout); READWRITE(nLockTime); - - return nSerSize; } /** Compute the hash of this CMutableTransaction. This is computed on the @@ -360,9 +345,8 @@ public: IMPLEMENT_SERIALIZE; template - inline size_t SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { - bool fRead = boost::is_same(); - size_t nSerSize = 0; + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + bool fRead = ser_action.ForRead(); if (!fRead) { uint64_t nVal = CompressAmount(txout.nValue); READWRITE(VARINT(nVal)); @@ -373,7 +357,6 @@ public: } CScriptCompressor cscript(REF(txout.scriptPubKey)); READWRITE(cscript); - return nSerSize; } }; @@ -430,10 +413,8 @@ public: IMPLEMENT_SERIALIZE; template - inline size_t SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { - size_t nSerSize = 0; + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { READWRITE(vprevout); - return nSerSize; } }; @@ -465,9 +446,7 @@ public: IMPLEMENT_SERIALIZE; template - inline size_t SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { - size_t nSerSize = 0; - + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { READWRITE(this->nVersion); nVersion = this->nVersion; READWRITE(hashPrevBlock); @@ -475,8 +454,6 @@ public: READWRITE(nTime); READWRITE(nBits); READWRITE(nNonce); - - return nSerSize; } void SetNull() @@ -526,13 +503,9 @@ public: IMPLEMENT_SERIALIZE; template - inline size_t SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { - size_t nSerSize = 0; - + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { READWRITE(*(CBlockHeader*)this); READWRITE(vtx); - - return nSerSize; } void SetNull() @@ -580,14 +553,10 @@ struct CBlockLocator IMPLEMENT_SERIALIZE; template - inline size_t SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { - size_t nSerSize = 0; - + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { if (!(nType & SER_GETHASH)) READWRITE(nVersion); READWRITE(vHave); - - return nSerSize; } void SetNull() -- cgit v1.2.3