From 092c1a90df20e6dcbd4f0d75af447b57b39d19a9 Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Fri, 9 Dec 2016 16:31:52 -0800 Subject: [PATCH] coins: undo coins fixes. --- lib/blockchain/coins.js | 12 +++--------- lib/blockchain/coinview.js | 2 ++ lib/blockchain/undocoins.js | 3 +-- lib/mempool/mempool.js | 6 +++--- lib/primitives/block.js | 12 +++++++++++- lib/primitives/coin.js | 9 +++++---- lib/primitives/input.js | 11 ++++++++++- lib/primitives/mtx.js | 11 ++++++++++- lib/primitives/tx.js | 12 +++++++++++- lib/wallet/txdb.js | 20 +++++++++----------- test/chain-test.js | 2 +- test/mempool-test.js | 2 +- test/wallet-test.js | 2 +- 13 files changed, 68 insertions(+), 36 deletions(-) diff --git a/lib/blockchain/coins.js b/lib/blockchain/coins.js index 45c7b800..6d81d3d0 100644 --- a/lib/blockchain/coins.js +++ b/lib/blockchain/coins.js @@ -213,8 +213,6 @@ Coins.prototype.spend = function spend(index) { if (!entry || entry.spent) return; - // this.outputs[index] = null; - // this.cleanup(); entry.spent = true; return entry; @@ -587,6 +585,7 @@ CoinEntry.prototype.reader = function reader() { CoinEntry.prototype.toCoin = function toCoin(coins, index) { var coin = new Coin(); + var output = this.toOutput(); // Load in all necessary properties // from the parent Coins object. @@ -595,13 +594,8 @@ CoinEntry.prototype.toCoin = function toCoin(coins, index) { coin.height = coins.height; coin.hash = coins.hash; coin.index = index; - - if (this.output) { - coin.script = this.output.script; - coin.value = this.output.value; - } else { - decompress.coin(coin, this.reader()); - } + coin.script = output.script; + coin.value = output.value; return coin; }; diff --git a/lib/blockchain/coinview.js b/lib/blockchain/coinview.js index 38889a88..86842f09 100644 --- a/lib/blockchain/coinview.js +++ b/lib/blockchain/coinview.js @@ -6,6 +6,7 @@ 'use strict'; +var assert = require('assert'); var co = require('../utils/co'); var Coins = require('./coins'); var UndoCoins = require('./undocoins'); @@ -144,6 +145,7 @@ CoinView.prototype.spendFrom = function spendFrom(coins, index) { undo.height = coins.height; undo.coinbase = coins.coinbase; undo.version = coins.version; + assert(undo.height !== -1); } return true; diff --git a/lib/blockchain/undocoins.js b/lib/blockchain/undocoins.js index ebf378dc..90181df8 100644 --- a/lib/blockchain/undocoins.js +++ b/lib/blockchain/undocoins.js @@ -140,6 +140,7 @@ UndoCoins.prototype.apply = function apply(view, outpoint) { assert(!view.unspent[hash]); view.unspent[hash] = coins; + coins.hash = hash; coins.coinbase = undo.coinbase; coins.height = undo.height; coins.version = undo.version; @@ -151,8 +152,6 @@ UndoCoins.prototype.apply = function apply(view, outpoint) { coins.addOutput(index, undo.toOutput()); assert(coins.has(index)); - - return coins.getCoin(index); }; /** diff --git a/lib/mempool/mempool.js b/lib/mempool/mempool.js index 6377362e..d939de86 100644 --- a/lib/mempool/mempool.js +++ b/lib/mempool/mempool.js @@ -406,7 +406,7 @@ Mempool.prototype.getCoin = function getCoin(hash, index) { if (index >= entry.tx.outputs.length) return; - return Coin.fromTX(entry.tx, index); + return Coin.fromTX(entry.tx, index, entry.height); }; /** @@ -1565,7 +1565,7 @@ Mempool.prototype.trackEntry = function trackEntry(entry, view) { if (output.script.isUnspendable()) continue; - coin = Coin.fromTX(tx, i); + coin = Coin.fromTX(tx, i, entry.height); this.coinIndex.addCoin(coin); } @@ -1610,7 +1610,7 @@ Mempool.prototype.untrackEntry = function untrackEntry(entry) { if (output.script.isUnspendable()) continue; - coin = Coin.fromTX(tx, i); + coin = Coin.fromTX(tx, i, entry.height); this.coinIndex.removeCoin(coin); } diff --git a/lib/primitives/block.js b/lib/primitives/block.js index 61d00f47..f609acf5 100644 --- a/lib/primitives/block.js +++ b/lib/primitives/block.js @@ -606,7 +606,17 @@ Block.prototype.getPrevout = function getPrevout() { * @returns {Object} */ -Block.prototype.inspect = function inspect(view) { +Block.prototype.inspect = function inspect() { + return this.show(); +}; + +/** + * Inspect the block and return a more + * user-friendly representation of the data. + * @returns {Object} + */ + +Block.prototype.show = function show(view) { var commitmentHash = this.getCommitmentHash('hex'); return { hash: this.rhash(), diff --git a/lib/primitives/coin.js b/lib/primitives/coin.js index fc48d6af..aa6f475c 100644 --- a/lib/primitives/coin.js +++ b/lib/primitives/coin.js @@ -282,11 +282,12 @@ Coin.fromRaw = function fromRaw(data, enc) { * @param {Number} index */ -Coin.prototype.fromTX = function fromTX(tx, index) { +Coin.prototype.fromTX = function fromTX(tx, index, height) { assert(util.isNumber(index)); assert(index < tx.outputs.length); + assert(typeof height === 'number'); this.version = tx.version; - this.height = tx.height; + this.height = height; this.value = tx.outputs[index].value; this.script = tx.outputs[index].script; this.coinbase = tx.isCoinbase(); @@ -302,8 +303,8 @@ Coin.prototype.fromTX = function fromTX(tx, index) { * @returns {Coin} */ -Coin.fromTX = function fromTX(tx, index) { - return new Coin().fromTX(tx, index); +Coin.fromTX = function fromTX(tx, index, height) { + return new Coin().fromTX(tx, index, height); }; /** diff --git a/lib/primitives/input.js b/lib/primitives/input.js index 05c2a211..55e40909 100644 --- a/lib/primitives/input.js +++ b/lib/primitives/input.js @@ -224,7 +224,16 @@ Input.prototype.isCoinbase = function isCoinbase() { * @returns {Object} */ -Input.prototype.inspect = function inspect(coin) { +Input.prototype.inspect = function inspect() { + return this.show(); +}; + +/** + * Convert the input to a more user-friendly object. + * @returns {Object} + */ + +Input.prototype.show = function show(coin) { return { type: this.getType(coin), subtype: this.getSubtype(coin), diff --git a/lib/primitives/mtx.js b/lib/primitives/mtx.js index 56ca8d34..41aeb9b2 100644 --- a/lib/primitives/mtx.js +++ b/lib/primitives/mtx.js @@ -164,7 +164,7 @@ MTX.prototype.addInput = function addInput(coin, index) { if (coin instanceof TX) { input.fromTX(coin, index); - coin = Coin.fromTX(coin, index); + coin = Coin.fromTX(coin, index, -1); } if (coin instanceof Coin) { @@ -1329,6 +1329,15 @@ MTX.prototype._mutable = function _mutable() { */ MTX.prototype.inspect = function inspect() { + return this.show(); +}; + +/** + * Inspect the transaction. + * @returns {Object} + */ + +MTX.prototype.show = function show() { return TX.prototype.inspect.call(this, this.view); }; diff --git a/lib/primitives/tx.js b/lib/primitives/tx.js index f736aaf1..1cbd06e1 100644 --- a/lib/primitives/tx.js +++ b/lib/primitives/tx.js @@ -2001,7 +2001,17 @@ TX.prototype.toInv = function toInv() { * @returns {Object} */ -TX.prototype.inspect = function inspect(view) { +TX.prototype.inspect = function inspect() { + return this.show(); +}; + +/** + * Inspect the transaction and return a more + * user-friendly representation of the data. + * @returns {Object} + */ + +TX.prototype.show = function show(view) { var rate = 0; var fee = 0; diff --git a/lib/wallet/txdb.js b/lib/wallet/txdb.js index 173ba9ca..aa567ff5 100644 --- a/lib/wallet/txdb.js +++ b/lib/wallet/txdb.js @@ -439,7 +439,7 @@ TXDB.prototype.resolveOutputs = co(function* resolveOutputs(tx, block, resolved) var flags = constants.flags.MANDATORY_VERIFY_FLAGS; var hash = tx.hash('hex'); var i, j, input, output, key; - var orphans, orphan, coin, valid; + var orphans, orphan, valid; if (!resolved) resolved = []; @@ -460,8 +460,6 @@ TXDB.prototype.resolveOutputs = co(function* resolveOutputs(tx, block, resolved) delete this.orphans[key]; - coin = Coin.fromTX(tx, i); - // Note that their might be multiple // orphans per input, either due to // double spends or an adversary @@ -479,7 +477,7 @@ TXDB.prototype.resolveOutputs = co(function* resolveOutputs(tx, block, resolved) // We can finally verify this input. if (this.options.verify && orphan.tx.height === -1) - valid = yield orphan.tx.verifyInputAsync(orphan.index, coin, flags); + valid = yield orphan.tx.verifyInputAsync(orphan.index, output, flags); // If it's valid and fully resolved, // we can resolve _its_ outputs. @@ -613,7 +611,7 @@ TXDB.prototype.resolveInput = co(function* resolveInput(tx, index, path) { assert(stx); // Crete the credit and add the undo coin. - credit = Credit.fromTX(tx, index); + credit = Credit.fromTX(tx, index, tx.height); this.spendCredit(credit, stx, spent.index); @@ -1111,7 +1109,7 @@ TXDB.prototype.insert = co(function* insert(tx, block) { continue; } - credit = Credit.fromTX(tx, i); + credit = Credit.fromTX(tx, i, tx.height); this.pending.coin++; this.pending.unconfirmed += output.value; @@ -1426,7 +1424,7 @@ TXDB.prototype.erase = co(function* erase(tx) { details.setOutput(i, path); - credit = Credit.fromTX(tx, i); + credit = Credit.fromTX(tx, i, tx.height); this.pending.coin--; this.pending.unconfirmed -= output.value; @@ -2981,8 +2979,8 @@ Credit.prototype.toRaw = function toRaw() { * @returns {Credit} */ -Credit.prototype.fromTX = function fromTX(tx, index) { - this.coin.fromTX(tx, index); +Credit.prototype.fromTX = function fromTX(tx, index, height) { + this.coin.fromTX(tx, index, height); this.spent = false; return this; }; @@ -2994,8 +2992,8 @@ Credit.prototype.fromTX = function fromTX(tx, index) { * @returns {Credit} */ -Credit.fromTX = function fromTX(tx, index) { - return new Credit().fromTX(tx, index); +Credit.fromTX = function fromTX(tx, index, height) { + return new Credit().fromTX(tx, index, height); }; /** diff --git a/test/chain-test.js b/test/chain-test.js index 5f391212..bee7280d 100644 --- a/test/chain-test.js +++ b/test/chain-test.js @@ -225,7 +225,7 @@ describe('Chain', function() { yield chain.add(block); tx = block.txs[1]; - output = bcoin.coin.fromTX(tx, 1); + output = bcoin.coin.fromTX(tx, 1, chain.height); coin = yield chain.db.getCoin(tx.hash('hex'), 1); diff --git a/test/mempool-test.js b/test/mempool-test.js index e23833fa..62205f94 100644 --- a/test/mempool-test.js +++ b/test/mempool-test.js @@ -58,7 +58,7 @@ describe('Mempool', function() { mempool.trackEntry(entry, funding.view); - return bcoin.coin.fromTX(funding, 0); + return bcoin.coin.fromTX(funding, 0, -1); } it('should open mempool', cob(function* () { diff --git a/test/wallet-test.js b/test/wallet-test.js index d9edf76d..91521d8d 100644 --- a/test/wallet-test.js +++ b/test/wallet-test.js @@ -216,7 +216,7 @@ describe('Wallet', function() { .addOutput(w.getAddress(), 24000) .addOutput(w.getAddress(), 24000); - doubleSpend = bcoin.coin.fromTX(t1, 0); + doubleSpend = bcoin.coin.fromTX(t1, 0, -1); // balance: 49000 yield w.sign(t2);