diff --git a/lib/bcoin/chaindb.js b/lib/bcoin/chaindb.js index c5b5e32f..0ff282f6 100644 --- a/lib/bcoin/chaindb.js +++ b/lib/bcoin/chaindb.js @@ -874,7 +874,8 @@ ChainDB.prototype.removeBlock = function removeBlock(hash, batch, callback) { ChainDB.prototype.connectBlock = function connectBlock(block, view, batch, callback) { var self = this; - var undo = new BufferWriter(); + var undo = new bcoin.coinview(); + var hasUndo = false; var i, j, tx, input, output, key, addresses, address, hash, coins, raw; if (this.options.spv) { @@ -916,7 +917,8 @@ ChainDB.prototype.connectBlock = function connectBlock(block, view, batch, callb batch.del(layout.C(address, input.prevout.hash, input.prevout.index)); } - Framer.coin(input.coin, false, undo); + hasUndo = true; + undo.addCoin(input.coin); } for (j = 0; j < tx.outputs.length; j++) { @@ -947,8 +949,8 @@ ChainDB.prototype.connectBlock = function connectBlock(block, view, batch, callb } } - if (undo.written > 0) - batch.put(layout.u(block.hash()), undo.render()); + if (hasUndo) + batch.put(layout.u(block.hash()), undo.toRaw()); this.emit('add block', block); @@ -1395,16 +1397,7 @@ ChainDB.prototype.getCoinView = function getCoinView(block, callback) { ChainDB.prototype.getUndoCoins = function getUndoCoins(hash, callback) { return this.db.fetch(layout.u(hash), function(data) { - var p = new BufferReader(data); - var coins = []; - var coin; - - while (p.left()) { - coin = Parser.parseCoin(p, false); - coins.push(new bcoin.coin(coin)); - } - - return coins; + return bcoin.coinview.fromRaw(data); }, callback); }; @@ -1416,7 +1409,7 @@ ChainDB.prototype.getUndoCoins = function getUndoCoins(hash, callback) { ChainDB.prototype.getUndoView = function getUndoView(block, callback) { var self = this; - var i, j, k, tx, input, coin; + var i, j, tx, input; return this.getCoinView(block, function(err, view) { if (err) @@ -1429,7 +1422,7 @@ ChainDB.prototype.getUndoView = function getUndoView(block, callback) { if (!coins) return callback(null, view); - for (i = 0, k = 0; i < block.txs.length; i++) { + for (i = 0; i < block.txs.length; i++) { tx = block.txs[i]; if (tx.isCoinbase()) @@ -1437,11 +1430,8 @@ ChainDB.prototype.getUndoView = function getUndoView(block, callback) { for (j = 0; j < tx.inputs.length; j++) { input = tx.inputs[j]; - coin = coins[k++]; - coin.hash = input.prevout.hash; - coin.index = input.prevout.index; - input.coin = coin; - view.addCoin(coin); + input.coin = coins.spend(input.prevout.hash, input.prevout.index); + view.addCoin(input.coin); } } diff --git a/lib/bcoin/coinview.js b/lib/bcoin/coinview.js index 83950f18..b556ec01 100644 --- a/lib/bcoin/coinview.js +++ b/lib/bcoin/coinview.js @@ -8,6 +8,8 @@ var bcoin = require('./env'); var utils = bcoin.utils; var assert = utils.assert; +var BufferReader = require('./reader'); +var BufferWriter = require('./writer'); /** * A collections of {@link Coins} objects. @@ -96,6 +98,36 @@ CoinView.prototype.spend = function spend(hash, index) { return this.coins[hash].spend(index); }; +CoinView.prototype.toRaw = function toRaw() { + var keys = Object.keys(this.coins); + var p = new BufferWriter(); + var out = []; + var i, hash; + + for (i = 0; i < keys.length; i++) { + hash = keys[i]; + p.writeHash(hash); + p.writeVarBytes(this.coins[hash].toRaw()); + } + + return p.render(); +}; + +CoinView.fromRaw = function fromRaw(data) { + var p = new BufferReader(data, true); + var map = {}; + var hash, coins; + + while (p.left()) { + hash = p.readHash('hex'); + coins = bcoin.coins.fromRaw(p.readVarBytes()); + coins.hash = hash; + map[hash] = coins; + } + + return new CoinView(map); +}; + /** * Fill transaction(s) with coins. * @param {TX} tx