From 769b50c999367dada9f3912f350c89fc474d69e9 Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Sat, 6 Feb 2016 16:16:02 -0800 Subject: [PATCH] rename output.prev to coin. --- lib/bcoin.js | 1 + lib/bcoin/address.js | 2 +- lib/bcoin/coin.js | 130 +++++++++++++++++++++++++++++++++++++++++++ lib/bcoin/input.js | 2 +- lib/bcoin/output.js | 105 +--------------------------------- lib/bcoin/tx-pool.js | 4 +- lib/bcoin/tx.js | 39 ++++++++++--- lib/bcoin/wallet.js | 2 +- 8 files changed, 169 insertions(+), 116 deletions(-) create mode 100644 lib/bcoin/coin.js diff --git a/lib/bcoin.js b/lib/bcoin.js index ef6f8010..9ead06b7 100644 --- a/lib/bcoin.js +++ b/lib/bcoin.js @@ -23,6 +23,7 @@ bcoin.protocol = require('./bcoin/protocol'); bcoin.script = require('./bcoin/script'); bcoin.input = require('./bcoin/input'); bcoin.output = require('./bcoin/output'); +bcoin.coin = require('./bcoin/coin'); bcoin.tx = require('./bcoin/tx'); bcoin.txPool = require('./bcoin/tx-pool'); bcoin.block = require('./bcoin/block'); diff --git a/lib/bcoin/address.js b/lib/bcoin/address.js index db52c8e6..be8e897e 100644 --- a/lib/bcoin/address.js +++ b/lib/bcoin/address.js @@ -340,7 +340,7 @@ Address.prototype.ownOutput = function ownOutput(tx, index) { var keys = this.keys; var outputs = tx.outputs; - if ((tx instanceof bcoin.output) || (tx instanceof bcoin.output.prev)) + if ((tx instanceof bcoin.output) || (tx instanceof bcoin.coin)) outputs = [tx]; outputs = outputs.filter(function(output, i) { diff --git a/lib/bcoin/coin.js b/lib/bcoin/coin.js new file mode 100644 index 00000000..f2c8000d --- /dev/null +++ b/lib/bcoin/coin.js @@ -0,0 +1,130 @@ +/** + * coin.js - coin object for bcoin + * Copyright (c) 2014-2015, Fedor Indutny (MIT License) + * https://github.com/indutny/bcoin + */ + +var bn = require('bn.js'); +var bcoin = require('../bcoin'); +var inherits = require('inherits'); +var utils = bcoin.utils; +var assert = utils.assert; +var constants = bcoin.protocol.constants; + +/** + * Coin + */ + +// This is basically a UTXO/Coin object. It is immutable once instantiated. It +// needs to store 5 properties: the tx hash, output index, output value, output +// script, and the block height the transaction was mined (to later calculate +// age). + +function Coin(tx, index) { + var options; + + if (!(this instanceof Coin)) + return new Coin(tx, index); + + if (tx instanceof Coin) + return tx; + + if (tx instanceof bcoin.tx) { + this.hash = tx.hash('hex'); + this.index = index; + this.value = tx.outputs[index].value; + this.script = tx.outputs[index].script; + this.height = tx.getHeight(); + } else { + options = tx; + this.hash = options.hash; + this.index = options.index; + this.value = options.value; + this.script = options.script; + this.height = options.height; + } + + if (utils.isBuffer(this.hash)) + this.hash = utils.toHex(this.hash); + + this.rhash = utils.revHex(this.hash); + + assert(typeof this.hash === 'string'); + assert(utils.isFinite(this.index)); + assert(this.value instanceof bn); + assert(Array.isArray(this.script)); + assert(utils.isFinite(this.height)); + + // Object.freeze(this); +} + +inherits(Coin, bcoin.output); + +Coin.prototype.__defineGetter__('chain', function() { + return this._chain || bcoin.chain.global; +}); + +Coin.prototype.getConfirmations = function getConfirmations() { + var top; + + if (!this.chain) + return 0; + + top = this.chain.height(); + + if (this.height === -1) + return 0; + + if (top < this.height) + return 1; + + return top - this.height + 1; +}; + +Coin.prototype.__defineGetter__('confirmations', function() { + return this.getConfirmations(); +}); + +Coin.prototype.getAge = function getAge() { + var age = this.getConfirmations(); + + if (age === -1) + age = 0; + + if (age !== 0) + age += 1; + + return age; +}; + +Coin.prototype.__defineGetter__('age', function() { + return this.getAge(); +}); + +Coin.prototype.toJSON = function toJSON() { + return { + hash: this.hash, + index: this.index, + value: utils.btc(this.value), + script: utils.toHex(bcoin.script.encode(this.script)), + height: this.height, + address: this.getAddress() + }; +}; + +Coin.fromJSON = function fromJSON(json) { + return new Coin({ + hash: json.hash, + index: json.index, + value: utils.satoshi(json.value), + script: bcoin.script.decode(utils.toArray(json.script, 'hex')), + height: json.height, + address: json.address + }); +}; + +/** + * Expose + */ + +module.exports = Coin; diff --git a/lib/bcoin/input.js b/lib/bcoin/input.js index f17eb67b..7f270f50 100644 --- a/lib/bcoin/input.js +++ b/lib/bcoin/input.js @@ -29,7 +29,7 @@ function Input(options) { }; if (options.output) - this.output = bcoin.output.prev(options.output); + this.output = bcoin.coin(options.output); if (utils.isBuffer(this.prevout.hash)) this.prevout.hash = utils.toHex(this.prevout.hash); diff --git a/lib/bcoin/output.js b/lib/bcoin/output.js index 1a7be03a..e3ef3c78 100644 --- a/lib/bcoin/output.js +++ b/lib/bcoin/output.js @@ -292,111 +292,8 @@ Output.prototype.inspect = function inspect() { }; }; -// This is basically a UTXO/Coin object. It is immutable once instantiated. It -// needs to store 5 properties: the tx hash, output index, output value, output -// script, and the block height the transaction was mined (to later calculate -// age). - -function Prevout(tx, index) { - var options; - - if (!(this instanceof Prevout)) - return new Prevout(tx, index); - - if (tx instanceof Prevout) - return tx; - - if (tx instanceof bcoin.tx) { - this.hash = tx.hash('hex'); - this.index = index; - this.value = tx.outputs[index].value; - this.script = tx.outputs[index].script; - this.height = tx.getHeight(); - } else { - options = tx; - this.hash = options.hash; - this.index = options.index; - this.value = options.value; - this.script = options.script; - this.height = options.height; - } - - if (utils.isBuffer(this.hash)) - this.hash = utils.toHex(this.hash); - - assert(typeof this.hash === 'string'); - assert(utils.isFinite(this.index)); - assert(this.value instanceof bn); - assert(Array.isArray(this.script)); - assert(utils.isFinite(this.height)); - - Object.freeze(this); -} - -inherits(Prevout, Output); - -Prevout.prototype.__defineGetter__('chain', function() { - return this._chain || bcoin.chain.global; -}); - -Prevout.prototype.getConfirmations = function getConfirmations() { - var top; - - if (!this.chain) - return 0; - - top = this.chain.height(); - - if (this.height === -1) - return 0; - - return top - this.height + 1; -}; - -Prevout.prototype.__defineGetter__('confirmations', function() { - return this.getConfirmations(); -}); - -Prevout.prototype.getAge = function getAge() { - var age = this.getConfirmations(); - - if (age === -1) - age = 0; - - if (age !== 0) - age += 1; - - return age; -}; - -Prevout.prototype.__defineGetter__('age', function() { - return this.getAge(); -}); - -Prevout.prototype.toJSON = function toJSON() { - return { - hash: this.hash, - index: this.index, - value: utils.btc(this.value), - script: utils.toHex(bcoin.script.encode(this.script)), - height: this.height - }; -}; - -Prevout.fromJSON = function fromJSON(json) { - return new Prevout({ - hash: json.hash, - index: json.index, - value: utils.satoshi(json.value), - script: bcoin.script.decode(utils.toArray(json.script, 'hex')), - height: json.height - }); -}; - /** * Expose */ -exports = Output; -exports.prev = Prevout; -module.exports = exports; +module.exports = Output; diff --git a/lib/bcoin/tx-pool.js b/lib/bcoin/tx-pool.js index 9efed078..80f734e5 100644 --- a/lib/bcoin/tx-pool.js +++ b/lib/bcoin/tx-pool.js @@ -176,7 +176,7 @@ TXPool.prototype.add = function add(tx, noWrite, strict) { assert(index !== -1); assert(orphan.tx.inputs[index].prevout.hash === tx.hash('hex')); assert(orphan.tx.inputs[index].prevout.index === i); - orphan.tx.inputs[index].output = bcoin.output.prev(tx, i); + orphan.tx.inputs[index].output = bcoin.coin(tx, i); // Verify that input script is correct, if not - add output to unspent // and remove orphan from storage @@ -210,7 +210,7 @@ TXPool.prototype.add = function add(tx, noWrite, strict) { delete this._orphans[key]; if (!orphans) { - this._unspent[key] = bcoin.output.prev(tx, i); + this._unspent[key] = bcoin.coin(tx, i); updated = true; } } diff --git a/lib/bcoin/tx.js b/lib/bcoin/tx.js index 5d1efa64..ead12590 100644 --- a/lib/bcoin/tx.js +++ b/lib/bcoin/tx.js @@ -126,7 +126,7 @@ TX.prototype.input = TX.prototype.addInput; // tx._addInput({ hash: hash, index: index }) // tx._addInput({ tx: tx, index: index }) TX.prototype._addInput = function _addInput(options, index) { - var input, ex, i, prevout; + var coin, input, ex, i, prevout; if (options instanceof TX) { options = { tx: options, index: index }; @@ -141,16 +141,16 @@ TX.prototype._addInput = function _addInput(options, index) { options.sequence = options.seq; if (!options.prevout) { - if (options instanceof bcoin.output.prev) { + if (options instanceof bcoin.coin) { options = { prevout: { hash: options.hash, index: options.index }, output: options }; } else if (options.tx) { - var prev = bcoin.output.prev(options.tx, options.index); + coin = bcoin.coin(options.tx, options.index); options = { - prevout: { hash: prev.hash, index: prev.index }, - output: prev, + prevout: { hash: coin.hash, index: coin.index }, + output: coin, script: options.script, sequence: options.sequence }; @@ -1445,7 +1445,7 @@ TX.prototype.fillPrevout = function fillPrevout(txs) { inputs = this.inputs.filter(function(input) { if (!input.output && txs[input.prevout.hash]) - input.output = bcoin.output.prev(txs[input.prevout.hash], input.prevout.index); + input.output = bcoin.coin(txs[input.prevout.hash], input.prevout.index); return !!input.output; }, this); @@ -1646,7 +1646,7 @@ TX.prototype.getPriority = function getPriority() { value.iadd(input.output.value.muln(age)); } - return priority.divn(size); + return value.divn(size); }; TX.prototype.isFree = function isFree() { @@ -1679,6 +1679,9 @@ TX.prototype.getConfirmations = function getConfirmations() { if (height === -1) return 0; + if (top < height) + return 1; + return top - height + 1; }; @@ -1686,6 +1689,18 @@ TX.prototype.getValue = function getValue() { return this.getOutputValue(); }; +TX.prototype.hasType = function hasType(type) { + for (var i = 0; i < this.inputs.length; i++) { + if (bcoin.script.getInputType(this.inputs[i].script) === type) + return true; + } + for (var i = 0; i < this.outputs.length; i++) { + if (bcoin.script.getType(this.outputs[i].script) === type) + return true; + } + return false; +}; + TX.prototype.__defineGetter__('chain', function() { return this._chain || bcoin.chain.global; }); @@ -1756,6 +1771,9 @@ TX.prototype.toJSON = function toJSON() { changeAddress: this.changeAddress, changeIndex: this.changeIndex, hardFee: this.hardFee ? utils.btc(this.hardFee) : null, + outputs: this.inputs.map(function(input) { + return input.output ? input.output.toJSON() : null; + }), tx: utils.toHex(this.render()) }; }; @@ -1786,6 +1804,13 @@ TX.fromJSON = function fromJSON(json) { tx.block = json.block || null; tx.ps = json.ps; + json.outputs.forEach(function(output, i) { + if (!output) + return; + + tx.inputs[i].output = bcoin.coin.fromJSON(output); + }); + return tx; }; diff --git a/lib/bcoin/wallet.js b/lib/bcoin/wallet.js index fcb33ccd..ba0e2649 100644 --- a/lib/bcoin/wallet.js +++ b/lib/bcoin/wallet.js @@ -832,7 +832,7 @@ Wallet.prototype.ownInput = function ownInput(tx, index) { }; Wallet.prototype.ownOutput = function ownOutput(tx, index) { - if ((tx instanceof bcoin.output) || (tx instanceof bcoin.output.prev)) { + if ((tx instanceof bcoin.output) || (tx instanceof bcoin.coin)) { var output = tx; var scriptAddress = output.getScriptAddress(); if (this._addressTable[scriptAddress] != null)