consistent naming.

This commit is contained in:
Christopher Jeffrey 2016-03-28 13:20:00 -07:00
parent 96a92ae29b
commit af6ac736bf
20 changed files with 217 additions and 323 deletions

View File

@ -297,10 +297,10 @@ Address.prototype.scriptInputs = function scriptInputs(tx, index) {
if (index != null && index !== i)
return total;
if (!input.output)
if (!input.coin)
return total;
if (!self.ownOutput(input.output))
if (!self.ownOutput(input.coin))
return total;
if (tx.scriptInput(i, self))
@ -323,10 +323,10 @@ Address.prototype.signInputs = function signInputs(tx, type, index) {
if (index != null && index !== i)
return total;
if (!input.output)
if (!input.coin)
return total;
if (!self.ownOutput(input.output))
if (!self.ownOutput(input.coin))
return total;
if (tx.signInput(i, self, type))
@ -351,10 +351,10 @@ Address.prototype.sign = function sign(tx, type, index) {
return total;
// Filter inputs that this wallet own
if (!input.output)
if (!input.coin)
return total;
if (!self.ownOutput(input.output))
if (!self.ownOutput(input.coin))
return total;
if (tx.sign(i, self, type))

View File

@ -645,7 +645,7 @@ Chain.prototype._checkInputs = function _checkInputs(block, prev, flags, peer, c
input = tx.inputs[j];
// Ensure tx is not double spending an output
if (!input.output) {
if (!input.coin) {
utils.debug('Block is using spent inputs: %s (tx: %s, output: %s)',
block.rhash, tx.rhash,
utils.revHex(input.prevout.hash) + '/' + input.prevout.index);
@ -668,13 +668,13 @@ Chain.prototype._checkInputs = function _checkInputs(block, prev, flags, peer, c
block.rhash, tx.rhash, j);
utils.debug(input);
utils.debug('Signature Hash v0: %s',
utils.toHex(tx.signatureHash(j, input.output.script, 'all', 0)));
utils.toHex(tx.signatureHash(j, input.coin.script, 'all', 0)));
utils.debug('Signature Hash v1: %s',
utils.toHex(tx.signatureHash(j, input.output.script, 'all', 1)));
utils.toHex(tx.signatureHash(j, input.coin.script, 'all', 1)));
utils.debug('Raw Script: %s',
utils.toHex(input.output.script.encode()));
utils.toHex(input.coin.script.encode()));
utils.debug('Reserialized Script: %s',
utils.toHex(input.output.script.clone().encode()));
utils.toHex(input.coin.script.clone().encode()));
if (height < network.checkpoints.lastHeight)
throw new Error('BUG: Bad inputs in historical data!');
return callback(null, false);

View File

@ -587,7 +587,7 @@ ChainDB.prototype.connectBlock = function connectBlock(block, batch, callback) {
if (tx.isCoinbase())
return;
assert(input.output);
assert(input.coin);
if (self.options.indexAddress) {
address = input.getAddress();
@ -659,7 +659,7 @@ ChainDB.prototype.disconnectBlock = function disconnectBlock(hash, batch, callba
if (tx.isCoinbase())
return;
assert(input.output);
assert(input.coin);
if (self.options.indexAddress) {
address = input.getAddress();
@ -680,7 +680,7 @@ ChainDB.prototype.disconnectBlock = function disconnectBlock(hash, batch, callba
batch.put('u/t/'
+ input.prevout.hash
+ '/' + input.prevout.index,
input.output.toRaw());
input.coin.toRaw());
});
tx.outputs.forEach(function(output, i) {
@ -708,14 +708,14 @@ ChainDB.prototype.disconnectBlock = function disconnectBlock(hash, batch, callba
});
};
ChainDB.prototype.fillCoin = function fillCoin(tx, callback) {
ChainDB.prototype.fillCoins = function fillCoins(tx, callback) {
var self = this;
callback = utils.asyncify(callback);
if (Array.isArray(tx)) {
return utils.forEachSerial(tx, function(tx, next) {
self.fillCoin(tx, next);
self.fillCoins(tx, next);
}, function(err) {
if (err)
return callback(err);
@ -727,7 +727,7 @@ ChainDB.prototype.fillCoin = function fillCoin(tx, callback) {
return callback(null, tx);
utils.forEachSerial(tx.inputs, function(input, next) {
if (input.output)
if (input.coin)
return next();
self.getCoin(input.prevout.hash, input.prevout.index, function(err, coin) {
@ -735,7 +735,7 @@ ChainDB.prototype.fillCoin = function fillCoin(tx, callback) {
return callback(err);
if (coin)
input.output = coin;
input.coin = coin;
next();
});
@ -766,7 +766,7 @@ ChainDB.prototype.fillTX = function fillTX(tx, callback) {
if (this.prune) {
return utils.forEachSerial(tx.inputs, function(input, next) {
if (input.output)
if (input.coin)
return next();
self._getPruneCoin(input.prevout.hash, input.prevout.index, function(err, coin) {
@ -774,7 +774,7 @@ ChainDB.prototype.fillTX = function fillTX(tx, callback) {
return callback(err);
if (coin)
input.output = coin;
input.coin = coin;
next();
});
@ -786,7 +786,7 @@ ChainDB.prototype.fillTX = function fillTX(tx, callback) {
}
utils.forEachSerial(tx.inputs, function(input, next) {
if (input.output)
if (input.coin)
return next();
self.getTX(input.prevout.hash, function(err, tx) {
@ -794,7 +794,7 @@ ChainDB.prototype.fillTX = function fillTX(tx, callback) {
return next(err);
if (tx)
input.output = bcoin.coin(tx, input.prevout.index);
input.coin = bcoin.coin(tx, input.prevout.index);
next();
});
@ -1076,7 +1076,7 @@ ChainDB.prototype._getTXBlock = function _getTXBlock(hash, callback) {
};
ChainDB.prototype.fillBlock = function fillBlock(block, callback) {
return this.fillCoin(block.txs, function(err) {
return this.fillCoins(block.txs, function(err) {
var coins, i, tx, hash, j, input, id;
if (err)
@ -1091,8 +1091,8 @@ ChainDB.prototype.fillBlock = function fillBlock(block, callback) {
for (j = 0; j < tx.inputs.length; j++) {
input = tx.inputs[j];
id = input.prevout.hash + '/' + input.prevout.index;
if (!input.output && coins[id]) {
input.output = coins[id];
if (!input.coin && coins[id]) {
input.coin = coins[id];
delete coins[id];
}
}
@ -1121,8 +1121,8 @@ ChainDB.prototype.fillTXBlock = function fillTXBlock(block, callback) {
for (j = 0; j < tx.inputs.length; j++) {
input = tx.inputs[j];
id = input.prevout.hash + '/' + input.prevout.index;
if (!input.output && coins[id]) {
input.output = coins[id];
if (!input.coin && coins[id]) {
input.coin = coins[id];
delete coins[id];
}
}
@ -1258,12 +1258,12 @@ ChainDB.prototype._pruneBlock = function _pruneBlock(block, batch, callback) {
return;
tx.inputs.forEach(function(input) {
assert(input.output);
assert(input.coin);
batch.put('u/x/'
+ input.prevout.hash
+ '/' + input.prevout.index,
input.output.toRaw());
input.coin.toRaw());
batch.put('u/q/'
+ futureHeight

View File

@ -101,13 +101,13 @@ Coins.prototype.fill = function fill(tx, spend) {
if (input.prevout.hash !== this.hash)
continue;
if (!input.output) {
if (!input.coin) {
if (spend)
input.output = this.spend(input.prevout.index);
input.coin = this.spend(input.prevout.index);
else
input.output = this.get(input.prevout.index);
input.coin = this.get(input.prevout.index);
if (!input.output)
if (!input.coin)
res = false;
}
}

View File

@ -349,17 +349,17 @@ Fullnode.prototype.getTXByAddress = function getTXByAddress(addresses, callback)
});
};
Fullnode.prototype.fillCoin = function fillCoin(tx, callback) {
Fullnode.prototype.fillCoins = function fillCoins(tx, callback) {
var self = this;
this.mempool.fillCoin(tx, function(err) {
this.mempool.fillCoins(tx, function(err) {
if (err)
return callback(err);
if (tx.hasPrevout())
if (tx.hasCoins())
return callback(null, tx);
self.chain.db.fillCoin(tx, callback);
self.chain.db.fillCoins(tx, callback);
});
};
@ -370,7 +370,7 @@ Fullnode.prototype.fillTX = function fillTX(tx, callback) {
if (err)
return callback(err);
if (tx.hasPrevout())
if (tx.hasCoins())
return callback(null, tx);
self.chain.db.fillTX(tx, callback);

View File

@ -103,7 +103,7 @@ Provider.prototype.fillTX = function fillTX(tx, callback) {
assert(false);
};
Provider.prototype.fillCoin = function fillCoin(tx, callback) {
Provider.prototype.fillCoins = function fillCoins(tx, callback) {
assert(false);
};

View File

@ -26,8 +26,8 @@ function Input(options, tx) {
this.witness = options.witness || new bcoin.script.witness([]);
this._mutable = !tx || (tx instanceof bcoin.mtx);
if (options.output)
this.output = bcoin.coin(options.output);
if (options.coin)
this.coin = bcoin.coin(options.coin);
if (Buffer.isBuffer(this.prevout.hash))
this.prevout.hash = utils.toHex(this.prevout.hash);
@ -47,8 +47,8 @@ Input.prototype.getType = function getType() {
if (this.isCoinbase())
return 'coinbase';
if (this.output)
return this.output.getType();
if (this.coin)
return this.coin.getType();
if (this._type)
return this._type;
@ -106,8 +106,8 @@ Input.prototype.getAddress = function getAddress() {
if (this.isCoinbase())
return;
if (this.output)
return this.output.getAddress();
if (this.coin)
return this.coin.getAddress();
if (this._address)
return this._address;
@ -132,23 +132,6 @@ Input.prototype.isFinal = function isFinal() {
return this.sequence === 0xffffffff;
};
Input.prototype.getLocktime = function getLocktime() {
var output, redeem;
assert(this.output);
output = this.output;
redeem = output.script;
if (redeem.isScripthash())
redeem = this.script.getRedeem();
if (redeem[1] !== 'checklocktimeverify')
return;
return redeem.getLocktime();
};
Input.prototype.isCoinbase = function isCoinbase() {
return +this.prevout.hash === 0;
};
@ -183,12 +166,12 @@ Input.prototype.getID = function getID() {
Input.prototype.inspect = function inspect() {
var redeem = this.getRedeem();
var output;
var coin;
if (this.output) {
output = this.output.inspect();
if (this.coin) {
coin = this.coin.inspect();
} else {
output = {
coin = {
type: 'unknown',
version: 1,
height: -1,
@ -205,12 +188,12 @@ Input.prototype.inspect = function inspect() {
type: this.getType(),
subtype: this.getSubtype(),
address: this.getAddress(),
value: utils.btc(output.value),
value: utils.btc(coin.value),
script: bcoin.script.format(this.script),
witness: bcoin.script.format(this.witness),
redeem: redeem ? bcoin.script.format(redeem) : null,
sequence: this.sequence,
output: output
coin: coin
};
};
@ -220,7 +203,7 @@ Input.prototype.toJSON = function toJSON() {
hash: utils.revHex(this.prevout.hash),
index: this.prevout.index
},
output: this.output ? this.output.toJSON() : null,
coin: this.coin ? this.coin.toJSON() : null,
script: utils.toHex(this.script.encode()),
witness: utils.toHex(this.witness.encode()),
sequence: this.sequence
@ -233,7 +216,7 @@ Input._fromJSON = function _fromJSON(json) {
hash: utils.revHex(json.prevout.hash),
index: json.prevout.index
},
output: json.output ? bcoin.coin._fromJSON(json.output) : null,
coin: json.coin ? bcoin.coin._fromJSON(json.coin) : null,
script: new bcoin.script(new Buffer(json.script, 'hex')),
witness: new bcoin.script.witness(new Buffer(json.witness, 'hex')),
sequence: json.sequence

View File

@ -260,8 +260,8 @@ Mempool.prototype.fillTX = function fillTX(tx, callback) {
return this.tx.fillTX(tx, callback);
};
Mempool.prototype.fillCoin = function fillCoin(tx, callback) {
return this.tx.fillCoin(tx, callback);
Mempool.prototype.fillCoins = function fillCoins(tx, callback) {
return this.tx.fillCoins(tx, callback);
};
Mempool.prototype.has =
@ -340,11 +340,11 @@ Mempool.prototype.addTX = function addTX(tx, peer, callback, force) {
0));
}
self.node.fillCoin(tx, function(err) {
self.node.fillCoins(tx, function(err) {
if (err)
return callback(err);
if (!tx.hasPrevout()) {
if (!tx.hasCoins()) {
if (self.size > Mempool.MAX_MEMPOOL_SIZE) {
return callback(new VerifyError(
'insufficientfee',
@ -458,7 +458,7 @@ Mempool.prototype.verify = function verify(tx, callback) {
total = new bn(0);
for (i = 0; i < tx.inputs.length; i++) {
input = tx.inputs[i];
coin = input.output;
coin = input.coin;
if (coin.coinbase) {
if (self.chain.height - coin.height < constants.tx.coinbaseMaturity) {
@ -642,7 +642,7 @@ Mempool.prototype.storeOrphan = function storeOrphan(tx, callback, force) {
for (i = 0; i < tx.inputs.length; i++) {
input = tx.inputs[i];
if (!input.output)
if (!input.coin)
outputs[input.prevout.hash] = true;
}
@ -726,11 +726,11 @@ Mempool.prototype.resolveOrphans = function resolveOrphans(tx, callback, force)
}
orphan.inputs.forEach(function(input) {
if (!input.output && input.prevout.hash === hash)
input.output = bcoin.coin(tx, input.prevout.index);
if (!input.coin && input.prevout.hash === hash)
input.coin = bcoin.coin(tx, input.prevout.index);
});
if (orphan.hasPrevout()) {
if (orphan.hasCoins()) {
batch.del('m/D/' + orphanHash);
return self.verify(orphan, function(err) {
if (err) {

View File

@ -158,7 +158,7 @@ Miner.prototype.addTX = function addTX(tx) {
// Cannot calculate fee if we don't have the prev_out.
// Could possibly just burn some coins.
if (this.options.burn === false) {
if (!tx.hasPrevout())
if (!tx.hasCoins())
return false;
}
@ -189,7 +189,7 @@ Miner.prototype.addTX = function addTX(tx) {
this.block.txs.push(tx);
// Calculate our new reward fee
if (tx.hasPrevout())
if (tx.hasCoins())
this.fee.iadd(tx.getFee());
// Update coinbase value

View File

@ -129,7 +129,7 @@ MTX.prototype.addInput = function addInput(options, index) {
if (options instanceof bcoin.coin) {
options = {
prevout: { hash: options.hash, index: options.index },
output: options
coin: options
};
}
@ -162,7 +162,7 @@ MTX.prototype.scriptInput = function scriptInput(index, addr) {
assert(input);
// We should have previous outputs by now.
assert(input.output);
assert(input.coin);
// Optimization: Don't bother with any below
// calculation if the output is already templated.
@ -174,11 +174,11 @@ MTX.prototype.scriptInput = function scriptInput(index, addr) {
// address map to avoid unnecessary calculation.
// A hash table lookup may be faster than all
// the nonsense below.
if (!addr.ownOutput(input.output))
if (!addr.ownOutput(input.coin))
return false;
// Get the previous output's script
prev = input.output.script;
prev = input.coin.script;
// This is easily the hardest part about building a transaction
// with segwit: figuring out where the redeem script and witness
@ -353,10 +353,10 @@ MTX.prototype.signInput = function signInput(index, addr, type) {
assert(input);
// We should have previous outputs by now.
assert(input.output);
assert(input.coin);
// Get the previous output's subscript
prev = input.output.script;
prev = input.coin.script;
vector = input.script.code;
len = vector.length;
@ -543,11 +543,11 @@ MTX.prototype.isSigned = function isSigned(m) {
// We can't check for signatures unless
// we have the previous output.
if (!input.output)
if (!input.coin)
return false;
// Get the prevout's subscript
prev = input.output.script;
prev = input.coin.script;
// Script length, needed for multisig
vector = input.script.code;
@ -660,7 +660,7 @@ MTX.prototype.addOutput = function addOutput(obj, value) {
};
MTX.prototype.scriptOutput = function scriptOutput(index, options) {
var output, script, keys, m, n, hash, flags, address, redeem;
var output;
if (options instanceof bcoin.output)
return;
@ -696,10 +696,10 @@ MTX.prototype.maxSize = function maxSize(maxM, maxN) {
size = 0;
witness = false;
assert(input.output);
assert(input.coin);
// Get the previous output's subscript
prev = input.output.script;
prev = input.coin.script;
// If we have access to the redeem script,
// we can use it to calculate size much easier.
@ -793,7 +793,7 @@ MTX.prototype.maxSize = function maxSize(maxM, maxN) {
return total;
};
MTX.prototype.selectCoins = function selectCoins(unspent, options) {
MTX.prototype.selectCoins = function selectCoins(coins, options) {
var tx = this.clone();
var outputValue = tx.getOutputValue();
var totalkb = 1;
@ -815,12 +815,12 @@ MTX.prototype.selectCoins = function selectCoins(unspent, options) {
if (!options.selection || options.selection === 'age') {
// Oldest unspents first
unspent = unspent.slice().sort(function(a, b) {
coins = coins.slice().sort(function(a, b) {
return a.height - b.height;
});
} else if (options.selection === 'random' || options.selection === 'all') {
// Random unspents
unspent = unspent.slice().sort(function() {
coins = coins.slice().sort(function() {
return Math.random() > 0.5 ? 1 : -1;
});
}
@ -838,12 +838,12 @@ MTX.prototype.selectCoins = function selectCoins(unspent, options) {
function addCoins() {
var i, index;
for (i = lastAdded; i < unspent.length; i++) {
for (i = lastAdded; i < coins.length; i++) {
// Add new inputs until MTX will have enough
// funds to cover both minimum post cost
// and fee.
tx.addInput(unspent[i]);
chosen.push(unspent[i]);
tx.addInput(coins[i]);
chosen.push(coins[i]);
lastAdded++;
if (options.wallet)
@ -887,14 +887,20 @@ MTX.prototype.selectCoins = function selectCoins(unspent, options) {
// break;
// }
newkb = Math.ceil(size / 1024) - totalkb;
fee.iaddn(newkb * minFee);
totalkb += newkb;
if (options.accurate) {
newkb = size / 1024;
fee = new bn(newkb * minFee | 0);
totalkb = newkb;
} else {
newkb = Math.ceil(size / 1024) - totalkb;
fee.iaddn(newkb * minFee);
totalkb += newkb;
}
// Failed to get enough funds, add more inputs.
if (!isFull())
addCoins();
} while (!isFull() && lastAdded < unspent.length);
} while (!isFull() && lastAdded < coins.length);
}
if (!isFull()) {
@ -937,7 +943,8 @@ MTX.prototype.selectCoins = function selectCoins(unspent, options) {
};
};
MTX.prototype.fill = function fill(unspent, options) {
MTX.prototype.fill = function fill(coins, options) {
var self = this;
var result, err;
if (!options || typeof options !== 'object') {
@ -947,10 +954,10 @@ MTX.prototype.fill = function fill(unspent, options) {
};
}
assert(unspent);
assert(coins);
assert(options.changeAddress);
result = this.selectCoins(unspent, options);
result = this.selectCoins(coins, options);
if (!result.coins) {
err = new Error('Could not fill transaction');
@ -959,8 +966,8 @@ MTX.prototype.fill = function fill(unspent, options) {
}
result.coins.forEach(function(coin) {
this.addInput(coin);
}, this);
self.addInput(coin);
});
if (result.change.cmpn(constants.tx.dustThreshold) < 0) {
// Do nothing. Change is added to fee.
@ -1014,34 +1021,6 @@ MTX.prototype.sortMembers = function sortMembers() {
}
};
MTX.prototype.getTargetLocktime = function getTargetLocktime() {
var bestValue = 0;
var i, locktime, bestType;
for (i = 0; i < this.inputs.length; i++) {
locktime = this.inputs[i].getLocktime();
if (!locktime)
continue;
// Incompatible types
if (bestType && bestType !== locktime.type)
return;
bestType = locktime.type;
if (locktime.value < bestValue)
continue;
bestValue = locktime.value;
}
return {
type: bestType || 'height',
value: bestValue
};
};
MTX.prototype.avoidFeeSniping = function avoidFeeSniping(height) {
if (height == null) {
if (!this.chain)
@ -1062,34 +1041,13 @@ MTX.prototype.avoidFeeSniping = function avoidFeeSniping(height) {
MTX.prototype.setLocktime = function setLocktime(locktime) {
var i, input;
this.locktime = locktime;
for (i = 0; i < this.inputs.length; i++) {
input = this.inputs[i];
if (input.sequence === 0xffffffff)
input.sequence = 0;
}
};
MTX.prototype.increaseFee = function increaseFee(unspent, address, fee) {
var i, input;
this.inputs.length = 0;
if (this.changeIndex !== -1) {
this.outputs.splice(this.changeIndex, 1);
this.changeIndex = -1;
input.sequence = 0xffffffff - 1;
}
if (!fee)
fee = this.getFee().add(new bn(10000));
this.fill(unspent, address, fee);
for (i = 0; i < this.inputs.length; i++) {
input = this.inputs[i];
input.sequence = 0xffffffff - 1;
}
this.locktime = locktime;
};
MTX._fromJSON = bcoin.tx._fromJSON;

View File

@ -1233,8 +1233,8 @@ Pool.prototype.isWatched = function(tx, bloom) {
return true;
// Test the prev_out script
if (input.output) {
if (testScript(input.output.script.code))
if (input.coin) {
if (testScript(input.coin.script.code))
return true;
}

View File

@ -1376,41 +1376,6 @@ Script.prototype.getSize = function getSize() {
return this.encode().length;
};
Script.prototype._locktime = function _locktime() {
if (this.code.length < 2)
return;
if (!Buffer.isBuffer(this.code[0]))
return;
if (this.code[1] !== 'checklocktimeverify')
return;
return this.code[0];
};
Script.prototype.isLocktime = function isLocktime() {
return this._locktime() != null;
};
Script.prototype.getLocktime = function getLocktime() {
var locktime = this._locktime();
if (!locktime)
return;
try {
locktime = Script.num(locktime, null, 4).toNumber();
} catch (e) {
locktime = 0;
}
if (locktime < constants.locktimeThreshold)
return { type: 'height', value: locktime };
return { type: 'time', value: locktime };
};
Script.prototype.getInputAddress = function getInputAddress(prev) {
return Script.getInputAddress(this.code, prev, false);
};
@ -2238,10 +2203,10 @@ Script.format = function format(code) {
scripts.push(code.script);
if (code.witness.length > 0)
scripts.push({ code: code.witness.items });
if (code.output) {
scripts.push(code.output.script);
if (code.output.script.isScripthash())
scripts.push(code.output.script.getRedeem());
if (code.coin) {
scripts.push(code.coin.script);
if (code.coin.script.isScripthash())
scripts.push(code.coin.script.getRedeem());
}
} else if (code instanceof bcoin.output) {
scripts.push(code.script);

View File

@ -22,7 +22,7 @@ function TXPool(wallet, txs) {
this._wallet = wallet;
this._all = {};
this._unspent = {};
this._coins = {};
this._orphans = {};
this._lastTs = 0;
this._lastHeight = 0;
@ -57,10 +57,10 @@ TXPool.prototype.populate = function populate(txs) {
TXPool.prototype.add = function add(tx, noWrite) {
var hash = tx.hash('hex');
var updated = false;
var i, j, input, output, coin, unspent, orphan;
var i, j, input, output, coin, orphan;
var key, orphans, some;
this._wallet.fillPrevout(tx);
this._wallet.fillCoins(tx);
if (!this._wallet.ownInput(tx) && !this._wallet.ownOutput(tx))
return false;
@ -84,8 +84,8 @@ TXPool.prototype.add = function add(tx, noWrite) {
this._all[hash].index = tx.index;
this._all[hash].outputs.forEach(function(output, i) {
var key = hash + '/' + i;
if (this._unspent[key])
this._unspent[key].height = tx.height;
if (this._coins[key])
this._coins[key].height = tx.height;
}, this);
this._storeTX(hash, tx, noWrite);
this._lastTs = Math.max(tx.ts, this._lastTs);
@ -102,14 +102,14 @@ TXPool.prototype.add = function add(tx, noWrite) {
for (i = 0; i < tx.inputs.length; i++) {
input = tx.inputs[i];
key = input.prevout.hash + '/' + input.prevout.index;
unspent = this._unspent[key];
coin = this._coins[key];
if (unspent) {
if (coin) {
// Add TX to inputs and spend money
input.output = unspent;
input.coin = coin;
assert(input.prevout.hash === unspent.hash);
assert(input.prevout.index === unspent.index);
assert(input.prevout.hash === coin.hash);
assert(input.prevout.index === coin.index);
// Skip invalid transactions
if (!tx.verify(i))
@ -117,7 +117,7 @@ TXPool.prototype.add = function add(tx, noWrite) {
this._addInput(tx, i);
delete this._unspent[key];
delete this._coins[key];
updated = true;
continue;
}
@ -155,7 +155,7 @@ TXPool.prototype.add = function add(tx, noWrite) {
for (j = 0; j < orphans.length; j++) {
orphan = orphans[j];
orphan.tx.inputs[orphan.index].output = coin;
orphan.tx.inputs[orphan.index].coin = coin;
assert(orphan.tx.inputs[orphan.index].prevout.hash === hash);
assert(orphan.tx.inputs[orphan.index].prevout.index === i);
@ -178,7 +178,7 @@ TXPool.prototype.add = function add(tx, noWrite) {
delete this._orphans[key];
if (!orphans) {
this._unspent[key] = coin;
this._coins[key] = coin;
updated = true;
}
}
@ -203,7 +203,7 @@ TXPool.prototype.getTX = function getTX(hash) {
};
TXPool.prototype.getCoin = function getCoin(hash, index) {
return this._unspent[hash + '/' + index];
return this._coins[hash + '/' + index];
};
TXPool.prototype._storeTX = function _storeTX(hash, tx, noWrite) {
@ -225,8 +225,8 @@ TXPool.prototype._removeTX = function _removeTX(tx, noWrite) {
for (i = 0; i < tx.outputs.length; i++) {
key = hash + '/' + i;
if (this._unspent[key]) {
delete this._unspent[key];
if (this._coins[key]) {
delete this._coins[key];
this._removeOutput(tx, i);
}
}
@ -259,13 +259,13 @@ TXPool.prototype.removeTX = function removeTX(hash) {
for (i = 0; i < tx.inputs.length; i++) {
input = tx.inputs[i];
if (!input.output || !this._wallet.ownOutput(input.output))
if (!input.coin || !this._wallet.ownOutput(input.coin))
continue;
this._removeInput(input);
key = input.prevout.hash + '/' + input.prevout.index;
this._unspent[key] = input.output;
this._coins[key] = input.coin;
updated = true;
}
@ -297,8 +297,8 @@ TXPool.prototype.unconfirm = function unconfirm(hash) {
tx.index = -1;
tx.outputs.forEach(function(output, i) {
var key = hash + '/' + i;
if (this._unspent[key])
this._unspent[key].height = -1;
if (this._coins[key])
this._coins[key].height = -1;
}, this);
this._storeTX(hash, tx);
this._lastTs = Math.max(tx.ts, this._lastTs);
@ -357,12 +357,12 @@ TXPool.prototype._addInput = function _addInput(tx, i, remove) {
else
input = tx.inputs[i];
assert(input.output);
assert(input.coin);
if (!this._wallet.ownOutput(input.output))
if (!this._wallet.ownOutput(input.coin))
return;
prev = input.output;
prev = input.coin;
address = prev.getAddress();
if (!this._addresses[address]) {
@ -406,12 +406,12 @@ TXPool.prototype.getAll = function getAll(address) {
});
};
TXPool.prototype.getUnspent = function getUnspent(address) {
return Object.keys(this._unspent).map(function(key) {
return this._unspent[key];
}, this).filter(function(unspent) {
TXPool.prototype.getCoins = function getCoins(address) {
return Object.keys(this._coins).map(function(key) {
return this._coins[key];
}, this).filter(function(coin) {
if (address) {
if (!unspent.test(address))
if (!coin.test(address))
return false;
}
return true;
@ -457,23 +457,17 @@ TXPool.prototype.getBalance = function getBalance(address) {
return this._balance.clone();
};
TXPool.prototype.getBalanceUnspent = function getBalanceUnspent(address) {
TXPool.prototype.getBalanceCoins = function getBalanceCoins(address) {
var acc = new bn(0);
var unspent = this.getUnspent(address);
if (unspent.length === 0)
var coin = this.getCoins(address);
if (coin.length === 0)
return acc;
return unspent.reduce(function(acc, coin) {
return coin.reduce(function(acc, coin) {
return acc.iadd(coin.value);
}, acc);
};
// Legacy
TXPool.prototype.all = TXPool.prototype.getAll;
TXPool.prototype.unspent = TXPool.prototype.getUnspent;
TXPool.prototype.pending = TXPool.prototype.getPending;
TXPool.prototype.balance = TXPool.prototype.getBalance;
/**
* Expose
*/

View File

@ -332,7 +332,7 @@ TX.prototype.signatureHashV1 = function signatureHashV1(index, prev, type) {
p.writeHash(this.inputs[index].prevout.hash);
p.writeU32(this.inputs[index].prevout.index);
p.writeVarBytes(prev.encode());
p.write64(this.inputs[index].output.value);
p.write64(this.inputs[index].coin.value);
p.writeU32(this.inputs[index].sequence);
p.writeBytes(hashOutputs);
p.writeU32(this.locktime);
@ -362,7 +362,7 @@ TX.prototype.verify = function verify(index, force, flags) {
if (index != null && i !== index)
return true;
if (!input.output) {
if (!input.coin) {
utils.debug('Warning: Not all outputs available for tx.verify().');
return false;
}
@ -370,7 +370,7 @@ TX.prototype.verify = function verify(index, force, flags) {
return bcoin.script.verify(
input.script,
input.witness,
input.output.script,
input.coin.script,
this,
i,
flags
@ -396,7 +396,7 @@ TX.prototype.isCoinbase = function isCoinbase() {
};
TX.prototype.getFee = function getFee() {
if (!this.hasPrevout())
if (!this.hasCoins())
return new bn(0);
return this.getInputValue().sub(this.getOutputValue());
@ -408,11 +408,11 @@ TX.prototype.getInputValue = function getInputValue() {
if (this.inputs.length === 0)
return acc;
if (!this.hasPrevout())
if (!this.hasCoins())
return acc;
return this.inputs.reduce(function(acc, input) {
return acc.iadd(input.output.value);
return acc.iadd(input.coin.value);
}, acc);
};
@ -549,61 +549,55 @@ TX.prototype.testOutputs = function testOutputs(addressTable, index) {
return false;
};
TX.prototype.hasPrevout = function hasPrevout() {
TX.prototype.hasCoins = function hasCoins() {
if (this.inputs.length === 0)
return false;
// if (this.isCoinbase())
// return true;
return this.inputs.every(function(input) {
return !!input.output;
return !!input.coin;
});
};
TX.prototype.fillPrevout = function fillPrevout(txs, unspent) {
var inputs;
TX.prototype.fillCoins = function fillCoins(coins) {
var total = 0;
var inputs, txs, key, i, input;
if (txs instanceof TX) {
txs = [txs];
unspent = null;
} else if (txs instanceof bcoin.coin) {
unspent = [txs];
txs = null;
} else if (txs instanceof bcoin.txpool) {
unspent = txs._unspent;
txs = txs._all;
} else if (txs instanceof bcoin.wallet && txs.tx) {
unspent = txs.tx._unspent;
txs = txs.tx._all;
}
if (!Array.isArray(coins))
coins = [coins];
if (Array.isArray(txs)) {
txs = txs.reduce(function(out, tx) {
out[tx.hash('hex')] = tx;
if (Array.isArray(coins)) {
coins = coins.reduce(function(out, coin) {
if (coin instanceof TX) {
out[coin.hash('hex')] = coin;
} else {
assert(typeof coin.hash === 'string');
out[coin.hash + '/' + coin.index] = coin;
}
return out;
}, {});
}
if (Array.isArray(unspent)) {
unspent = unspent.reduce(function(out, coin) {
out[coin.hash + '/' + coin.index] = coin;
return out;
}, {});
}
for (i = 0; i < this.inputs.length; i++) {
input = this.inputs[i];
inputs = this.inputs.filter(function(input) {
var key;
if (!input.output) {
key = input.prevout.hash + '/' + input.prevout.index;
if (unspent && unspent[key])
input.output = unspent[key];
else if (txs && txs[input.prevout.hash])
input.output = bcoin.coin(txs[input.prevout.hash], input.prevout.index);
if (!input.coin) {
if (coins[input.prevout.hash]) {
input.coin = bcoin.coin(coins[input.prevout.hash], input.prevout.index);
} else {
key = input.prevout.hash + '/' + input.prevout.index;
if (coins[key])
input.coin = coins[key];
}
}
return !!input.output;
}, this);
if (input.coin)
total++;
}
return inputs.length === this.inputs.length;
return total === this.inputs.length;
};
TX.prototype.isFinal = function isFinal(height, ts) {
@ -630,10 +624,10 @@ TX.prototype._getSigops = function _getSigops(scriptHash, accurate) {
this.inputs.forEach(function(input) {
var prev;
if (!input.output)
if (!input.coin)
return;
prev = input.output.script;
prev = input.coin.script;
total += input.script.getSigops(accurate);
@ -666,10 +660,10 @@ TX.prototype.getSigops = function getSigops(scriptHash, accurate) {
this.inputs.forEach(function(input) {
var prev;
if (!input.output)
if (!input.coin)
return;
prev = input.output.script;
prev = input.coin.script;
if (prev.isScripthash())
prev = input.script.getRedeem();
@ -791,10 +785,10 @@ TX.prototype.isStandardInputs = function isStandardInputs(flags) {
for (i = 0; i < this.inputs.length; i++) {
input = this.inputs[i];
if (!input.output)
if (!input.coin)
return false;
args = input.output.script.getArgs();
args = input.coin.script.getArgs();
if (args < 0)
return false;
@ -813,7 +807,7 @@ TX.prototype.isStandardInputs = function isStandardInputs(flags) {
return false;
if ((flags & constants.flags.VERIFY_WITNESS)
&& input.output.isWitnessProgram()) {
&& input.coin.isWitnessProgram()) {
hadWitness = true;
// Input script must be empty.
@ -821,12 +815,12 @@ TX.prototype.isStandardInputs = function isStandardInputs(flags) {
return false;
// Verify the program in the output script
if (!this.isStandardProgram(input.witness, input.output.script, flags))
if (!this.isStandardProgram(input.witness, input.coin.script, flags))
return false;
}
if ((flags & constants.flags.VERIFY_P2SH)
&& input.output.script.isScripthash()) {
&& input.coin.script.isScripthash()) {
if (stack.length === 0)
return false;
@ -925,7 +919,7 @@ TX.prototype.getPriority = function getPriority(height, size) {
if (height === -1)
height = null;
if (!this.hasPrevout())
if (!this.hasCoins())
return new bn(0);
if (size == null)
@ -936,10 +930,10 @@ TX.prototype.getPriority = function getPriority(height, size) {
for (i = 0; i < this.inputs.length; i++) {
input = this.inputs[i];
if (!input.output)
if (!input.coin)
return new bn(0);
age = input.output.getConfirmations(height);
age = input.coin.getConfirmations(height);
if (age === -1)
age = 0;
@ -947,7 +941,7 @@ TX.prototype.getPriority = function getPriority(height, size) {
if (age !== 0)
age += 1;
sum.iadd(input.output.value.muln(age));
sum.iadd(input.coin.value.muln(age));
}
return sum.divn(size);
@ -956,7 +950,7 @@ TX.prototype.getPriority = function getPriority(height, size) {
TX.prototype.isFree = function isFree(height, size) {
var priority;
if (!this.hasPrevout())
if (!this.hasCoins())
return false;
if (height == null)
@ -1200,12 +1194,12 @@ TX.prototype.toExtended = function toExtended(saveCoins) {
if (saveCoins) {
p.writeVarint(this.inputs.length);
this.inputs.forEach(function(input) {
if (!input.output) {
if (!input.coin) {
p.writeVarint(0);
return;
}
p.writeVarBytes(bcoin.protocol.framer.coin(input.output, false));
p.writeVarBytes(bcoin.protocol.framer.coin(input.coin, false));
});
}
@ -1249,7 +1243,7 @@ TX._fromExtended = function _fromExtended(buf, saveCoins) {
coin.hash = tx.inputs[i].prevout.hash;
coin.index = tx.inputs[i].prevout.index;
coin.coinbase = false;
tx.inputs[i].output = new bcoin.coin(coin);
tx.inputs[i].coin = new bcoin.coin(coin);
}
}

View File

@ -314,7 +314,7 @@ TXPool.prototype._add = function add(tx, map, callback, force) {
if (coin) {
// Add TX to inputs and spend money
input.output = coin;
input.coin = coin;
// Skip invalid transactions
if (self.options.verify) {
@ -336,7 +336,7 @@ TXPool.prototype._add = function add(tx, map, callback, force) {
return next();
}
input.output = null;
input.coin = null;
self.isSpent(input.prevout.hash, input.prevout.index, function(err, spentBy) {
if (err)
@ -352,7 +352,7 @@ TXPool.prototype._add = function add(tx, map, callback, force) {
if (!prev)
return callback(new Error('Could not find double-spent coin.'));
input.output = bcoin.coin(prev, input.prevout.index);
input.coin = bcoin.coin(prev, input.prevout.index);
// Skip invalid transactions
if (self.options.verify) {
@ -422,7 +422,7 @@ TXPool.prototype._add = function add(tx, map, callback, force) {
if (!orphan.tx)
return next();
orphan.tx.inputs[orphan.index].output = coin;
orphan.tx.inputs[orphan.index].coin = coin;
assert(orphan.tx.inputs[orphan.index].prevout.hash === hash);
assert(orphan.tx.inputs[orphan.index].prevout.index === i);
@ -766,7 +766,7 @@ TXPool.prototype._remove = function remove(tx, map, callback, force) {
if (tx.isCoinbase())
return;
if (!input.output)
if (!input.coin)
return;
if (self.options.mapAddress) {
@ -786,7 +786,7 @@ TXPool.prototype._remove = function remove(tx, map, callback, force) {
batch.put(prefix + 'u/t/'
+ input.prevout.hash
+ '/' + input.prevout.index,
input.output.toRaw());
input.coin.toRaw());
batch.del(prefix + 's/t/'
+ input.prevout.hash
@ -1390,7 +1390,7 @@ TXPool.prototype.fillTX = function fillTX(tx, callback) {
return callback(null, tx);
utils.forEach(tx.inputs, function(input, next) {
if (input.output)
if (input.coin)
return next();
self.getTX(input.prevout.hash, function(err, tx) {
@ -1398,7 +1398,7 @@ TXPool.prototype.fillTX = function fillTX(tx, callback) {
return next(err);
if (tx)
input.output = bcoin.coin(tx, input.prevout.index);
input.coin = bcoin.coin(tx, input.prevout.index);
next();
});
@ -1409,12 +1409,12 @@ TXPool.prototype.fillTX = function fillTX(tx, callback) {
});
};
TXPool.prototype.fillCoin = function fillCoin(tx, callback) {
TXPool.prototype.fillCoins = function fillCoins(tx, callback) {
var self = this;
if (Array.isArray(tx)) {
return utils.forEachSerial(tx, function(tx, next) {
self.fillCoin(tx, function(err) {
self.fillCoins(tx, function(err) {
if (err)
return next(err);
@ -1429,7 +1429,7 @@ TXPool.prototype.fillCoin = function fillCoin(tx, callback) {
return callback(null, tx);
utils.forEach(tx.inputs, function(input, next) {
if (input.output)
if (input.coin)
return next();
self.getCoin(input.prevout.hash, input.prevout.index, function(err, coin) {
@ -1437,7 +1437,7 @@ TXPool.prototype.fillCoin = function fillCoin(tx, callback) {
return callback(err);
if (coin)
input.output = coin;
input.coin = coin;
next();
});
@ -1559,7 +1559,7 @@ TXPool.prototype.addUnchecked = function addUnchecked(tx, callback, force) {
if (tx.isCoinbase())
return;
assert(input.output);
assert(input.coin);
address = input.getAddress();
batch.del(prefix + 'u/t/' + key);
@ -1625,7 +1625,7 @@ TXPool.prototype.removeUnchecked = function removeUnchecked(hash, callback, forc
if (tx.isCoinbase())
return;
if (!input.output)
if (!input.coin)
return;
address = input.getAddress();

View File

@ -524,7 +524,7 @@ Wallet.prototype.fill = function fill(tx, options, callback) {
});
};
Wallet.prototype.fillPrevout = function fillPrevout(tx, callback) {
Wallet.prototype.fillCoins = function fillCoins(tx, callback) {
if (!this.provider)
return callback(new Error('No wallet provider available.'));
@ -615,7 +615,7 @@ Wallet.prototype.getInputPaths = function getInputPaths(tx) {
var i, input, output, address, path;
if (tx instanceof bcoin.input) {
path = this.getPath(tx.output.getAddress());
path = this.getPath(tx.coin.getAddress());
if (path)
paths.push(path);
return paths;
@ -623,7 +623,7 @@ Wallet.prototype.getInputPaths = function getInputPaths(tx) {
for (i = 0; i < tx.inputs.length; i++) {
input = tx.inputs[i];
output = input.output;
output = input.coin;
assert(output);
address = output.getAddress();

View File

@ -543,8 +543,8 @@ WalletDB.prototype.fillTX = function fillTX(tx, callback) {
return this.tx.fillTX(tx, callback);
};
WalletDB.prototype.fillCoin = function fillCoin(tx, callback) {
return this.tx.fillCoin(tx, callback);
WalletDB.prototype.fillCoins = function fillCoins(tx, callback) {
return this.tx.fillCoins(tx, callback);
};
WalletDB.prototype.removeBlockSPV = function removeBlockSPV(block, callback) {
@ -708,8 +708,8 @@ Provider.prototype.fillTX = function fillTX(tx, callback) {
return this.db.fillTX(tx, callback);
};
Provider.prototype.fillCoin = function fillCoin(tx, callback) {
return this.db.fillCoin(tx, callback);
Provider.prototype.fillCoins = function fillCoins(tx, callback) {
return this.db.fillCoins(tx, callback);
};
Provider.prototype.addTX = function addTX(tx, callback) {

View File

@ -36,7 +36,7 @@ describe('Wallet', function() {
hash: constants.oneHash,
index: 0
},
output: {
coin: {
version: 1,
height: 0,
value: new bn(70000),
@ -82,7 +82,7 @@ describe('Wallet', function() {
// balance: 11000
[t2, t3, t4, f1, fake].forEach(function(tx) {
tx.inputs.forEach(function(input) {
delete input.output;
delete input.coin;
});
});

View File

@ -49,7 +49,7 @@ describe('TX', function() {
it('should be verifiable', function() {
var tx = bcoin.tx(parser.parseTX(new Buffer(raw, 'hex')));
var p = bcoin.tx(parser.parseTX(new Buffer(inp, 'hex')));
tx.fillPrevout(p);
tx.fillCoins(p);
assert(tx.verify());
});

View File

@ -9,7 +9,7 @@ var dummyInput = {
hash: constants.zeroHash,
index: 0
},
output: {
coin: {
version: 1,
height: 0,
value: constants.maxMoney.clone(),