coin: safely handle coin.fromTX.
This commit is contained in:
parent
690c8840e0
commit
de18e92117
@ -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;
|
||||
});
|
||||
|
||||
/**
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
*/
|
||||
|
||||
Loading…
Reference in New Issue
Block a user