diff --git a/lib/blockchain/chain.js b/lib/blockchain/chain.js index 89807fee..8d49901f 100644 --- a/lib/blockchain/chain.js +++ b/lib/blockchain/chain.js @@ -1704,16 +1704,16 @@ Chain.prototype.hasPending = function hasPending(hash) { }; /** - * Get coin viewpoint. + * Get coin viewpoint (spent). * @method * @param {TX} tx * @returns {Promise} - Returns {@link CoinView}. */ -Chain.prototype.getCoinView = co(function* getCoinView(tx) { +Chain.prototype.getSpentView = co(function* getSpentView(tx) { var unlock = yield this.locker.lock(); try { - return yield this.db.getCoinView(tx); + return yield this.db.getSpentView(tx); } finally { unlock(); } diff --git a/lib/mempool/mempool.js b/lib/mempool/mempool.js index 8181c9d7..aaf80d93 100644 --- a/lib/mempool/mempool.js +++ b/lib/mempool/mempool.js @@ -29,6 +29,8 @@ var layout = require('./layout'); var LDB = require('../db/ldb'); var Fees = require('./fees'); var Map = require('../utils/map'); +var CoinView = require('../coins/coinview'); +var Coins = require('../coins/coins'); var VerifyError = errors.VerifyError; var VerifyResult = errors.VerifyResult; @@ -1603,7 +1605,22 @@ Mempool.prototype.isDoubleSpend = function isDoubleSpend(tx) { * Get coin viewpoint (lock). * @method * @param {TX} tx - * @param {CoinView} view + * @returns {Promise} - Returns {@link CoinView}. + */ + +Mempool.prototype.getSpentView = co(function* getSpentView(tx) { + var unlock = yield this.locker.lock(); + try { + return yield this.getCoinView(tx); + } finally { + unlock(); + } +}); + +/** + * Get coin viewpoint (no lock). + * @method + * @param {TX} tx * @returns {Promise} - Returns {@link CoinView}. */ @@ -1629,6 +1646,42 @@ Mempool.prototype.getCoinView = co(function* getCoinView(tx) { return view; }); +/** + * Get coin viewpoint (no lock). + * @method + * @param {TX} tx + * @returns {Promise} - Returns {@link CoinView}. + */ + +Mempool.prototype.getCoinView = co(function* getCoinView(tx) { + var view = new CoinView(); + var prevout = tx.getPrevout(); + var i, hash, entry, coins; + + for (i = 0; i < prevout.length; i++) { + hash = prevout[i]; + entry = this.getEntry(hash); + + if (entry) { + view.addTX(entry.tx, -1); + continue; + } + + coins = yield this.chain.db.getCoins(hash); + + if (!coins) { + coins = new Coins(); + coins.hash = hash; + view.add(coins); + continue; + } + + view.add(coins); + } + + return view; +}); + /** * Find missing outpoints. * @param {TX} tx diff --git a/lib/node/fullnode.js b/lib/node/fullnode.js index 8a0b6854..d736d073 100644 --- a/lib/node/fullnode.js +++ b/lib/node/fullnode.js @@ -465,6 +465,18 @@ FullNode.prototype.getMeta = co(function* getMeta(hash) { return yield this.chain.db.getMeta(hash); }); +/** + * Retrieve a spent coin viewpoint from mempool or chain database. + * @param {TXMeta} meta + * @returns {Promise} - Returns {@link CoinView}. + */ + +FullNode.prototype.getMetaView = co(function* getMetaView(meta) { + if (meta.height === -1) + return this.mempool.getSpentView(meta.tx); + return this.chain.getSpentView(meta.tx); +}); + /** * Retrieve transactions pertaining to an * address from the mempool or chain database.