coin: safely handle coin.fromTX.

This commit is contained in:
Christopher Jeffrey 2016-10-20 07:32:52 -07:00
parent 690c8840e0
commit de18e92117
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
4 changed files with 185 additions and 172 deletions

View File

@ -836,7 +836,7 @@ ChainDB.prototype.fillCoins = co(function* fillCoins(tx) {
var i, input, prevout, coin;
if (tx.isCoinbase())
return tx;
return;
for (i = 0; i < tx.inputs.length; i++) {
input = tx.inputs[i];
@ -847,11 +847,11 @@ ChainDB.prototype.fillCoins = co(function* fillCoins(tx) {
coin = yield this.getCoin(prevout.hash, prevout.index);
if (coin)
input.coin = coin;
}
if (!coin)
continue;
return tx;
input.coin = coin;
}
});
/**
@ -861,27 +861,31 @@ ChainDB.prototype.fillCoins = co(function* fillCoins(tx) {
*/
ChainDB.prototype.fillHistory = co(function* fillHistory(tx) {
var i, input, ptx;
var i, input, prevout, prev;
if (!this.options.indexTX)
return tx;
return;
if (tx.isCoinbase())
return tx;
return;
for (i = 0; i < tx.inputs.length; i++) {
input = tx.inputs[i];
prevout = input.prevout;
if (input.coin)
continue;
ptx = yield this.getTX(input.prevout.hash);
prev = yield this.getTX(prevout.hash);
if (ptx)
input.coin = Coin.fromTX(ptx, input.prevout.index);
if (!prev)
continue;
if (prevout.index >= prev.outputs.length)
continue;
input.coin = Coin.fromTX(prev, prevout.index);
}
return tx;
});
/**

View File

@ -458,16 +458,19 @@ Mempool.prototype.fillHistory = function fillHistory(tx) {
for (i = 0; i < tx.inputs.length; i++) {
input = tx.inputs[i];
prevout = input.prevout;
if (input.coin)
continue;
prevout = input.prevout;
prev = this.getTX(prevout.hash);
if (!prev)
continue;
if (prevout.index >= prev.outputs.length)
continue;
input.coin = Coin.fromTX(prev, prevout.index);
}
};
@ -486,11 +489,11 @@ Mempool.prototype.fillCoins = function fillCoins(tx) {
for (i = 0; i < tx.inputs.length; i++) {
input = tx.inputs[i];
prevout = input.prevout;
if (input.coin)
continue;
prevout = input.prevout;
coin = this.getCoin(prevout.hash, prevout.index);
if (!coin)
@ -1597,6 +1600,7 @@ Mempool.prototype.trackEntry = function trackEntry(entry) {
continue;
coin = Coin.fromTX(tx, i);
this.coinIndex.addCoin(coin);
}
}
@ -1641,6 +1645,7 @@ Mempool.prototype.untrackEntry = function untrackEntry(entry) {
continue;
coin = Coin.fromTX(tx, i);
this.coinIndex.removeCoin(coin);
}
}

View File

@ -1076,7 +1076,7 @@ TX.prototype.hasCoins = function hasCoins() {
TX.prototype.fillCoins = function fillCoins(coins) {
var result = true;
var i, input, hash, index, map, coin;
var i, input, hash, index, map, tx, coin;
if ((coins instanceof Coin)
|| (coins instanceof TX)) {
@ -1105,10 +1105,14 @@ TX.prototype.fillCoins = function fillCoins(coins) {
if (input.coin)
continue;
coin = coins[hash];
tx = coins[hash];
if (coin) {
input.coin = Coin.fromTX(coin, index);
if (tx) {
if (index < tx.outputs.length) {
input.coin = Coin.fromTX(tx, index);
continue;
}
result = false;
continue;
}

View File

@ -2049,25 +2049,6 @@ TXDB.prototype.getPending = co(function* getPending(account) {
return txs;
});
/**
* Get coins.
* @param {Number?} account
* @returns {Promise} - Returns {@link Coin}[].
*/
TXDB.prototype.getCoins = co(function* getCoins(account, all) {
var credits = yield this.getCredits(account, all);
var coins = [];
var i, credit;
for (i = 0; i < credits.length; i++) {
credit = credits[i];
coins.push(credit.coin);
}
return coins;
});
/**
* Get coins.
* @param {Number?} account
@ -2113,25 +2094,6 @@ TXDB.prototype.getCredits = co(function* getCredits(account, all) {
return unspent;
});
/**
* Get coins by account.
* @param {Number} account
* @returns {Promise} - Returns {@link Coin}[].
*/
TXDB.prototype.getAccountCoins = co(function* getAccountCoins(account, all) {
var credits = yield this.getAccountCredits(account, all);
var coins = [];
var i, credit;
for (i = 0; i < credits.length; i++) {
credit = credits[i];
coins.push(credit.coin);
}
return coins;
});
/**
* Get coins by account.
* @param {Number} account
@ -2161,36 +2123,6 @@ TXDB.prototype.getAccountCredits = co(function* getAccountCredits(account, all)
return credits;
});
/**
* Fill a transaction with coins (all historical coins).
* @param {TX} tx
* @returns {Promise} - Returns {@link TX}.
*/
TXDB.prototype.fillHistory = co(function* fillHistory(tx) {
var coins = [];
var i, input, credits, credit;
if (tx.isCoinbase())
return coins;
credits = yield this.getSpentCredits(tx);
for (i = 0; i < tx.inputs.length; i++) {
input = tx.inputs[i];
credit = credits[i];
if (!credit)
continue;
input.coin = credit.coin;
coins.push(credit.coin);
}
return coins;
});
/**
* Fill a transaction with coins (all historical coins).
* @param {TX} tx
@ -2226,6 +2158,74 @@ TXDB.prototype.getSpentCredits = co(function* getSpentCredits(tx) {
return credits;
});
/**
* Get coins.
* @param {Number?} account
* @returns {Promise} - Returns {@link Coin}[].
*/
TXDB.prototype.getCoins = co(function* getCoins(account, all) {
var credits = yield this.getCredits(account, all);
var coins = [];
var i, credit;
for (i = 0; i < credits.length; i++) {
credit = credits[i];
coins.push(credit.coin);
}
return coins;
});
/**
* Get coins by account.
* @param {Number} account
* @returns {Promise} - Returns {@link Coin}[].
*/
TXDB.prototype.getAccountCoins = co(function* getAccountCoins(account, all) {
var credits = yield this.getAccountCredits(account, all);
var coins = [];
var i, credit;
for (i = 0; i < credits.length; i++) {
credit = credits[i];
coins.push(credit.coin);
}
return coins;
});
/**
* Fill a transaction with coins (all historical coins).
* @param {TX} tx
* @returns {Promise} - Returns {@link TX}.
*/
TXDB.prototype.fillHistory = co(function* fillHistory(tx) {
var coins = [];
var i, input, credits, credit;
if (tx.isCoinbase())
return coins;
credits = yield this.getSpentCredits(tx);
for (i = 0; i < tx.inputs.length; i++) {
input = tx.inputs[i];
credit = credits[i];
if (!credit)
continue;
input.coin = credit.coin;
coins.push(credit.coin);
}
return coins;
});
/**
* Fill a transaction with coins.
* @param {TX} tx
@ -2236,7 +2236,7 @@ TXDB.prototype.fillCoins = co(function* fillCoins(tx) {
var i, input, prevout, credit;
if (tx.isCoinbase())
return tx;
return;
for (i = 0; i < tx.inputs.length; i++) {
input = tx.inputs[i];
@ -2255,8 +2255,6 @@ TXDB.prototype.fillCoins = co(function* fillCoins(tx) {
input.coin = credit.coin;
}
return tx;
});
/**
@ -2368,8 +2366,10 @@ TXDB.prototype.hasTX = function hasTX(hash) {
TXDB.prototype.getCoin = co(function* getCoin(hash, index) {
var credit = yield this.getCredit(hash, index);
if (!credit)
return;
return credit.coin;
});
@ -2786,6 +2786,88 @@ TXDBState.prototype.inspect = function inspect() {
return this.toJSON();
};
/**
* Credit (wrapped coin)
* @constructor
* @param {Coin} coin
* @param {Boolean?} spent
* @property {Coin} coin
* @property {Boolean} spent
*/
function Credit(coin, spent) {
if (!(this instanceof Credit))
return new Credit(coin, spent);
this.coin = coin || new Coin();
this.spent = spent || false;
}
/**
* Inject properties from serialized data.
* @private
* @param {Buffer} data
*/
Credit.prototype.fromRaw = function fromRaw(data) {
var p = BufferReader(data);
this.coin.fromRaw(p);
this.spent = p.readU8() === 1;
return this;
};
/**
* Instantiate credit from serialized data.
* @param {Buffer} data
* @returns {Credit}
*/
Credit.fromRaw = function fromRaw(data) {
return new Credit().fromRaw(data);
};
/**
* Serialize credit.
* @returns {Buffer}
*/
Credit.prototype.toRaw = function toRaw(writer) {
var p = BufferWriter(writer);
this.coin.toRaw(p);
p.writeU8(this.spent ? 1 : 0);
if (!writer)
p = p.render();
return p;
};
/**
* Inject properties from tx object.
* @private
* @param {TX} tx
* @param {Number} i
* @returns {Credit}
*/
Credit.prototype.fromTX = function fromTX(tx, i) {
this.coin.fromTX(tx, i);
this.spent = false;
return this;
};
/**
* Instantiate credit from transaction.
* @param {TX} tx
* @param {Number} i
* @returns {Credit}
*/
Credit.fromTX = function fromTX(tx, i) {
return new Credit().fromTX(tx, i);
};
/**
* Transaction Details
* @constructor
@ -2971,88 +3053,6 @@ DetailsMember.prototype.toJSON = function toJSON(network) {
};
};
/**
* Credit (wrapped coin)
* @constructor
* @param {Coin} coin
* @param {Boolean?} spent
* @property {Coin} coin
* @property {Boolean} spent
*/
function Credit(coin, spent) {
if (!(this instanceof Credit))
return new Credit(coin, spent);
this.coin = coin || new Coin();
this.spent = spent || false;
}
/**
* Inject properties from serialized data.
* @private
* @param {Buffer} data
*/
Credit.prototype.fromRaw = function fromRaw(data) {
var p = BufferReader(data);
this.coin.fromRaw(p);
this.spent = p.readU8() === 1;
return this;
};
/**
* Instantiate credit from serialized data.
* @param {Buffer} data
* @returns {Credit}
*/
Credit.fromRaw = function fromRaw(data) {
return new Credit().fromRaw(data);
};
/**
* Serialize credit.
* @returns {Buffer}
*/
Credit.prototype.toRaw = function toRaw(writer) {
var p = BufferWriter(writer);
this.coin.toRaw(p);
p.writeU8(this.spent ? 1 : 0);
if (!writer)
p = p.render();
return p;
};
/**
* Inject properties from tx object.
* @private
* @param {TX} tx
* @param {Number} i
* @returns {Credit}
*/
Credit.prototype.fromTX = function fromTX(tx, i) {
this.coin.fromTX(tx, i);
this.spent = false;
return this;
};
/**
* Instantiate credit from transaction.
* @param {TX} tx
* @param {Number} i
* @returns {Credit}
*/
Credit.fromTX = function fromTX(tx, i) {
return new Credit().fromTX(tx, i);
};
/*
* Helpers
*/