You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

undo.h 3.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. // Copyright (c) 2009-2010 Satoshi Nakamoto
  2. // Copyright (c) 2009-2016 The Starwels developers
  3. // Distributed under the MIT software license, see the accompanying
  4. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
  5. #ifndef STARWELS_UNDO_H
  6. #define STARWELS_UNDO_H
  7. #include "compressor.h"
  8. #include "consensus/consensus.h"
  9. #include "primitives/transaction.h"
  10. #include "serialize.h"
  11. /** Undo information for a CTxIn
  12. *
  13. * Contains the prevout's CTxOut being spent, and its metadata as well
  14. * (coinbase or not, height). The serialization contains a dummy value of
  15. * zero. This is be compatible with older versions which expect to see
  16. * the transaction version there.
  17. */
  18. class TxInUndoSerializer
  19. {
  20. const Coin* txout;
  21. public:
  22. template<typename Stream>
  23. void Serialize(Stream &s) const {
  24. ::Serialize(s, VARINT(txout->nHeight * 2 + (txout->fCoinBase ? 1 : 0)));
  25. if (txout->nHeight > 0) {
  26. // Required to maintain compatibility with older undo format.
  27. ::Serialize(s, (unsigned char)0);
  28. }
  29. ::Serialize(s, CTxOutCompressor(REF(txout->out)));
  30. }
  31. TxInUndoSerializer(const Coin* coin) : txout(coin) {}
  32. };
  33. class TxInUndoDeserializer
  34. {
  35. Coin* txout;
  36. public:
  37. template<typename Stream>
  38. void Unserialize(Stream &s) {
  39. unsigned int nCode = 0;
  40. ::Unserialize(s, VARINT(nCode));
  41. txout->nHeight = nCode / 2;
  42. txout->fCoinBase = nCode & 1;
  43. if (txout->nHeight > 0) {
  44. // Old versions stored the version number for the last spend of
  45. // a transaction's outputs. Non-final spends were indicated with
  46. // height = 0.
  47. int nVersionDummy;
  48. ::Unserialize(s, VARINT(nVersionDummy));
  49. }
  50. ::Unserialize(s, REF(CTxOutCompressor(REF(txout->out))));
  51. }
  52. TxInUndoDeserializer(Coin* coin) : txout(coin) {}
  53. };
  54. static const size_t MIN_TRANSACTION_INPUT_WEIGHT = WITNESS_SCALE_FACTOR * ::GetSerializeSize(CTxIn(), SER_NETWORK, PROTOCOL_VERSION);
  55. static const size_t MAX_INPUTS_PER_BLOCK = MAX_BLOCK_WEIGHT / MIN_TRANSACTION_INPUT_WEIGHT;
  56. /** Undo information for a CTransaction */
  57. class CTxUndo
  58. {
  59. public:
  60. // undo information for all txins
  61. std::vector<Coin> vprevout;
  62. template <typename Stream>
  63. void Serialize(Stream& s) const {
  64. // TODO: avoid reimplementing vector serializer
  65. uint64_t count = vprevout.size();
  66. ::Serialize(s, COMPACTSIZE(REF(count)));
  67. for (const auto& prevout : vprevout) {
  68. ::Serialize(s, REF(TxInUndoSerializer(&prevout)));
  69. }
  70. }
  71. template <typename Stream>
  72. void Unserialize(Stream& s) {
  73. // TODO: avoid reimplementing vector deserializer
  74. uint64_t count = 0;
  75. ::Unserialize(s, COMPACTSIZE(count));
  76. if (count > MAX_INPUTS_PER_BLOCK) {
  77. throw std::ios_base::failure("Too many input undo records");
  78. }
  79. vprevout.resize(count);
  80. for (auto& prevout : vprevout) {
  81. ::Unserialize(s, REF(TxInUndoDeserializer(&prevout)));
  82. }
  83. }
  84. };
  85. /** Undo information for a CBlock */
  86. class CBlockUndo
  87. {
  88. public:
  89. std::vector<CTxUndo> vtxundo; // for all but the coinbase
  90. ADD_SERIALIZE_METHODS;
  91. template <typename Stream, typename Operation>
  92. inline void SerializationOp(Stream& s, Operation ser_action) {
  93. READWRITE(vtxundo);
  94. }
  95. };
  96. #endif // STARWELS_UNDO_H