mirror of
https://github.com/dashpay/dash.git
synced 2024-12-28 13:32:47 +01:00
172f5fa738
Currently, the READWRITE macro cannot be passed any non-const temporaries, as the SerReadWrite function only accepts lvalue references. Deserializing into a temporary is very common, however. See for example things like 's >> VARINT(n)'. The VARINT macro produces a temporary wrapper that holds a reference to n. Fix this by accepting non-const rvalue references instead of lvalue references. We don't propagate the rvalue-ness down, as there are no useful optimizations that only apply to temporaries. Then use this new functionality to get rid of many (but not all) uses of the 'REF' macro (which casts away constness).
113 lines
3.4 KiB
C++
113 lines
3.4 KiB
C++
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
|
// Copyright (c) 2009-2017 The Bitcoin Core developers
|
|
// Distributed under the MIT software license, see the accompanying
|
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
|
|
#ifndef BITCOIN_UNDO_H
|
|
#define BITCOIN_UNDO_H
|
|
|
|
#include <compressor.h>
|
|
#include <consensus/consensus.h>
|
|
#include <primitives/transaction.h>
|
|
#include <serialize.h>
|
|
|
|
/** Undo information for a CTxIn
|
|
*
|
|
* Contains the prevout's CTxOut being spent, and its metadata as well
|
|
* (coinbase or not, height). The serialization contains a dummy value of
|
|
* zero. This is be compatible with older versions which expect to see
|
|
* the transaction version there.
|
|
*/
|
|
class TxInUndoSerializer
|
|
{
|
|
const Coin* txout;
|
|
|
|
public:
|
|
template<typename Stream>
|
|
void Serialize(Stream &s) const {
|
|
::Serialize(s, VARINT(txout->nHeight * 2 + (txout->fCoinBase ? 1 : 0)));
|
|
if (txout->nHeight > 0) {
|
|
// Required to maintain compatibility with older undo format.
|
|
::Serialize(s, (unsigned char)0);
|
|
}
|
|
::Serialize(s, CTxOutCompressor(REF(txout->out)));
|
|
}
|
|
|
|
explicit TxInUndoSerializer(const Coin* coin) : txout(coin) {}
|
|
};
|
|
|
|
class TxInUndoDeserializer
|
|
{
|
|
Coin* txout;
|
|
|
|
public:
|
|
template<typename Stream>
|
|
void Unserialize(Stream &s) {
|
|
unsigned int nCode = 0;
|
|
::Unserialize(s, VARINT(nCode));
|
|
txout->nHeight = nCode / 2;
|
|
txout->fCoinBase = nCode & 1;
|
|
if (txout->nHeight > 0) {
|
|
// Old versions stored the version number for the last spend of
|
|
// a transaction's outputs. Non-final spends were indicated with
|
|
// height = 0.
|
|
int nVersionDummy;
|
|
::Unserialize(s, VARINT(nVersionDummy));
|
|
}
|
|
::Unserialize(s, CTxOutCompressor(REF(txout->out)));
|
|
}
|
|
|
|
explicit TxInUndoDeserializer(Coin* coin) : txout(coin) {}
|
|
};
|
|
|
|
static const size_t MIN_TRANSACTION_INPUT_WEIGHT = WITNESS_SCALE_FACTOR * ::GetSerializeSize(CTxIn(), SER_NETWORK, PROTOCOL_VERSION);
|
|
static const size_t MAX_INPUTS_PER_BLOCK = MAX_BLOCK_WEIGHT / MIN_TRANSACTION_INPUT_WEIGHT;
|
|
|
|
/** Undo information for a CTransaction */
|
|
class CTxUndo
|
|
{
|
|
public:
|
|
// undo information for all txins
|
|
std::vector<Coin> vprevout;
|
|
|
|
template <typename Stream>
|
|
void Serialize(Stream& s) const {
|
|
// TODO: avoid reimplementing vector serializer
|
|
uint64_t count = vprevout.size();
|
|
::Serialize(s, COMPACTSIZE(REF(count)));
|
|
for (const auto& prevout : vprevout) {
|
|
::Serialize(s, TxInUndoSerializer(&prevout));
|
|
}
|
|
}
|
|
|
|
template <typename Stream>
|
|
void Unserialize(Stream& s) {
|
|
// TODO: avoid reimplementing vector deserializer
|
|
uint64_t count = 0;
|
|
::Unserialize(s, COMPACTSIZE(count));
|
|
if (count > MAX_INPUTS_PER_BLOCK) {
|
|
throw std::ios_base::failure("Too many input undo records");
|
|
}
|
|
vprevout.resize(count);
|
|
for (auto& prevout : vprevout) {
|
|
::Unserialize(s, TxInUndoDeserializer(&prevout));
|
|
}
|
|
}
|
|
};
|
|
|
|
/** Undo information for a CBlock */
|
|
class CBlockUndo
|
|
{
|
|
public:
|
|
std::vector<CTxUndo> vtxundo; // for all but the coinbase
|
|
|
|
ADD_SERIALIZE_METHODS;
|
|
|
|
template <typename Stream, typename Operation>
|
|
inline void SerializationOp(Stream& s, Operation ser_action) {
|
|
READWRITE(vtxundo);
|
|
}
|
|
};
|
|
|
|
#endif // BITCOIN_UNDO_H
|