1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2016 The Bitcoin Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
9 #include "compressor.h"
10 #include "consensus/consensus.h"
11 #include "primitives/transaction.h"
12 #include "serialize.h"
14 /** Undo information for a CTxIn
16 * Contains the prevout's CTxOut being spent, and its metadata as well
17 * (coinbase or not, height). The serialization contains a dummy value of
18 * zero. This is be compatible with older versions which expect to see
19 * the transaction version there.
21 class TxInUndoSerializer
26 template<typename Stream
>
27 void Serialize(Stream
&s
) const {
28 ::Serialize(s
, VARINT(txout
->nHeight
* 2 + (txout
->fCoinBase
? 1 : 0)));
29 if (txout
->nHeight
> 0) {
30 // Required to maintain compatibility with older undo format.
31 ::Serialize(s
, (unsigned char)0);
33 ::Serialize(s
, CTxOutCompressor(REF(txout
->out
)));
36 TxInUndoSerializer(const Coin
* coin
) : txout(coin
) {}
39 class TxInUndoDeserializer
44 template<typename Stream
>
45 void Unserialize(Stream
&s
) {
46 unsigned int nCode
= 0;
47 ::Unserialize(s
, VARINT(nCode
));
48 txout
->nHeight
= nCode
/ 2;
49 txout
->fCoinBase
= nCode
& 1;
50 if (txout
->nHeight
> 0) {
51 // Old versions stored the version number for the last spend of
52 // a transaction's outputs. Non-final spends were indicated with
55 ::Unserialize(s
, VARINT(nVersionDummy
));
57 ::Unserialize(s
, REF(CTxOutCompressor(REF(txout
->out
))));
60 TxInUndoDeserializer(Coin
* coin
) : txout(coin
) {}
63 static const size_t MAX_INPUTS_PER_BLOCK
= MAX_BLOCK_BASE_SIZE
/ ::GetSerializeSize(CTxIn(), SER_NETWORK
, PROTOCOL_VERSION
);
65 /** Undo information for a CTransaction */
69 // undo information for all txins
70 std::vector
<Coin
> vprevout
;
72 template <typename Stream
>
73 void Serialize(Stream
& s
) const {
74 // TODO: avoid reimplementing vector serializer
75 uint64_t count
= vprevout
.size();
76 ::Serialize(s
, COMPACTSIZE(REF(count
)));
77 for (const auto& prevout
: vprevout
) {
78 ::Serialize(s
, REF(TxInUndoSerializer(&prevout
)));
82 template <typename Stream
>
83 void Unserialize(Stream
& s
) {
84 // TODO: avoid reimplementing vector deserializer
86 ::Unserialize(s
, COMPACTSIZE(count
));
87 if (count
> MAX_INPUTS_PER_BLOCK
) {
88 throw std::ios_base::failure("Too many input undo records");
90 vprevout
.resize(count
);
91 for (auto& prevout
: vprevout
) {
92 ::Unserialize(s
, REF(TxInUndoDeserializer(&prevout
)));
97 /** Undo information for a CBlock */
101 std::vector
<CTxUndo
> vtxundo
; // for all but the coinbase
103 ADD_SERIALIZE_METHODS
;
105 template <typename Stream
, typename Operation
>
106 inline void SerializationOp(Stream
& s
, Operation ser_action
) {
111 #endif // BITCOIN_UNDO_H