Source: coins/undocoins.js

  1. /*!
  2. * undocoins.js - undocoins object for bcoin
  3. * Copyright (c) 2014-2017, Christopher Jeffrey (MIT License).
  4. * https://github.com/bcoin-org/bcoin
  5. */
  6. 'use strict';
  7. const assert = require('bsert');
  8. const bio = require('bufio');
  9. const CoinEntry = require('../coins/coinentry');
  10. /**
  11. * Undo Coins
  12. * Coins need to be resurrected from somewhere
  13. * during a reorg. The undo coins store all
  14. * spent coins in a single record per block
  15. * (in a compressed format).
  16. * @alias module:coins.UndoCoins
  17. * @property {UndoCoin[]} items
  18. */
  19. class UndoCoins {
  20. /**
  21. * Create undo coins.
  22. * @constructor
  23. */
  24. constructor() {
  25. this.items = [];
  26. }
  27. /**
  28. * Push coin entry onto undo coin array.
  29. * @param {CoinEntry}
  30. * @returns {Number}
  31. */
  32. push(coin) {
  33. return this.items.push(coin);
  34. }
  35. /**
  36. * Calculate undo coins size.
  37. * @returns {Number}
  38. */
  39. getSize() {
  40. let size = 0;
  41. size += 4;
  42. for (const coin of this.items)
  43. size += coin.getSize();
  44. return size;
  45. }
  46. /**
  47. * Serialize all undo coins.
  48. * @returns {Buffer}
  49. */
  50. toRaw() {
  51. const size = this.getSize();
  52. const bw = bio.write(size);
  53. bw.writeU32(this.items.length);
  54. for (const coin of this.items)
  55. coin.toWriter(bw);
  56. return bw.render();
  57. }
  58. /**
  59. * Inject properties from serialized data.
  60. * @private
  61. * @param {Buffer} data
  62. * @returns {UndoCoins}
  63. */
  64. fromRaw(data) {
  65. const br = bio.read(data);
  66. const count = br.readU32();
  67. for (let i = 0; i < count; i++)
  68. this.items.push(CoinEntry.fromReader(br));
  69. return this;
  70. }
  71. /**
  72. * Instantiate undo coins from serialized data.
  73. * @param {Buffer} data
  74. * @returns {UndoCoins}
  75. */
  76. static fromRaw(data) {
  77. return new this().fromRaw(data);
  78. }
  79. /**
  80. * Test whether the undo coins have any members.
  81. * @returns {Boolean}
  82. */
  83. isEmpty() {
  84. return this.items.length === 0;
  85. }
  86. /**
  87. * Render the undo coins.
  88. * @returns {Buffer}
  89. */
  90. commit() {
  91. const raw = this.toRaw();
  92. this.items.length = 0;
  93. return raw;
  94. }
  95. /**
  96. * Re-apply undo coins to a view, effectively unspending them.
  97. * @param {CoinView} view
  98. * @param {Outpoint} prevout
  99. */
  100. apply(view, prevout) {
  101. const undo = this.items.pop();
  102. assert(undo);
  103. view.addEntry(prevout, undo);
  104. }
  105. }
  106. /*
  107. * Expose
  108. */
  109. module.exports = UndoCoins;