Document assumptions that are being made to avoid NULL pointer dereferences
[bitcoinplatinum.git] / src / undo.h
bloba720de4ac5aa23587d9cf7dcbc28f113abe53cb2
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.
6 #ifndef BITCOIN_UNDO_H
7 #define BITCOIN_UNDO_H
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
23 const Coin* txout;
25 public:
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 explicit TxInUndoSerializer(const Coin* coin) : txout(coin) {}
39 class TxInUndoDeserializer
41 Coin* txout;
43 public:
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
53 // height = 0.
54 int nVersionDummy;
55 ::Unserialize(s, VARINT(nVersionDummy));
57 ::Unserialize(s, REF(CTxOutCompressor(REF(txout->out))));
60 explicit TxInUndoDeserializer(Coin* coin) : txout(coin) {}
63 static const size_t MIN_TRANSACTION_INPUT_WEIGHT = WITNESS_SCALE_FACTOR * ::GetSerializeSize(CTxIn(), SER_NETWORK, PROTOCOL_VERSION);
64 static const size_t MAX_INPUTS_PER_BLOCK = MAX_BLOCK_WEIGHT / MIN_TRANSACTION_INPUT_WEIGHT;
66 /** Undo information for a CTransaction */
67 class CTxUndo
69 public:
70 // undo information for all txins
71 std::vector<Coin> vprevout;
73 template <typename Stream>
74 void Serialize(Stream& s) const {
75 // TODO: avoid reimplementing vector serializer
76 uint64_t count = vprevout.size();
77 ::Serialize(s, COMPACTSIZE(REF(count)));
78 for (const auto& prevout : vprevout) {
79 ::Serialize(s, REF(TxInUndoSerializer(&prevout)));
83 template <typename Stream>
84 void Unserialize(Stream& s) {
85 // TODO: avoid reimplementing vector deserializer
86 uint64_t count = 0;
87 ::Unserialize(s, COMPACTSIZE(count));
88 if (count > MAX_INPUTS_PER_BLOCK) {
89 throw std::ios_base::failure("Too many input undo records");
91 vprevout.resize(count);
92 for (auto& prevout : vprevout) {
93 ::Unserialize(s, REF(TxInUndoDeserializer(&prevout)));
98 /** Undo information for a CBlock */
99 class CBlockUndo
101 public:
102 std::vector<CTxUndo> vtxundo; // for all but the coinbase
104 ADD_SERIALIZE_METHODS;
106 template <typename Stream, typename Operation>
107 inline void SerializationOp(Stream& s, Operation ser_action) {
108 READWRITE(vtxundo);
112 #endif // BITCOIN_UNDO_H