coins: undo coins fixes.
This commit is contained in:
parent
12b3274d33
commit
092c1a90df
@ -213,8 +213,6 @@ Coins.prototype.spend = function spend(index) {
|
|||||||
if (!entry || entry.spent)
|
if (!entry || entry.spent)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// this.outputs[index] = null;
|
|
||||||
// this.cleanup();
|
|
||||||
entry.spent = true;
|
entry.spent = true;
|
||||||
|
|
||||||
return entry;
|
return entry;
|
||||||
@ -587,6 +585,7 @@ CoinEntry.prototype.reader = function reader() {
|
|||||||
|
|
||||||
CoinEntry.prototype.toCoin = function toCoin(coins, index) {
|
CoinEntry.prototype.toCoin = function toCoin(coins, index) {
|
||||||
var coin = new Coin();
|
var coin = new Coin();
|
||||||
|
var output = this.toOutput();
|
||||||
|
|
||||||
// Load in all necessary properties
|
// Load in all necessary properties
|
||||||
// from the parent Coins object.
|
// from the parent Coins object.
|
||||||
@ -595,13 +594,8 @@ CoinEntry.prototype.toCoin = function toCoin(coins, index) {
|
|||||||
coin.height = coins.height;
|
coin.height = coins.height;
|
||||||
coin.hash = coins.hash;
|
coin.hash = coins.hash;
|
||||||
coin.index = index;
|
coin.index = index;
|
||||||
|
coin.script = output.script;
|
||||||
if (this.output) {
|
coin.value = output.value;
|
||||||
coin.script = this.output.script;
|
|
||||||
coin.value = this.output.value;
|
|
||||||
} else {
|
|
||||||
decompress.coin(coin, this.reader());
|
|
||||||
}
|
|
||||||
|
|
||||||
return coin;
|
return coin;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
var assert = require('assert');
|
||||||
var co = require('../utils/co');
|
var co = require('../utils/co');
|
||||||
var Coins = require('./coins');
|
var Coins = require('./coins');
|
||||||
var UndoCoins = require('./undocoins');
|
var UndoCoins = require('./undocoins');
|
||||||
@ -144,6 +145,7 @@ CoinView.prototype.spendFrom = function spendFrom(coins, index) {
|
|||||||
undo.height = coins.height;
|
undo.height = coins.height;
|
||||||
undo.coinbase = coins.coinbase;
|
undo.coinbase = coins.coinbase;
|
||||||
undo.version = coins.version;
|
undo.version = coins.version;
|
||||||
|
assert(undo.height !== -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@ -140,6 +140,7 @@ UndoCoins.prototype.apply = function apply(view, outpoint) {
|
|||||||
assert(!view.unspent[hash]);
|
assert(!view.unspent[hash]);
|
||||||
view.unspent[hash] = coins;
|
view.unspent[hash] = coins;
|
||||||
|
|
||||||
|
coins.hash = hash;
|
||||||
coins.coinbase = undo.coinbase;
|
coins.coinbase = undo.coinbase;
|
||||||
coins.height = undo.height;
|
coins.height = undo.height;
|
||||||
coins.version = undo.version;
|
coins.version = undo.version;
|
||||||
@ -151,8 +152,6 @@ UndoCoins.prototype.apply = function apply(view, outpoint) {
|
|||||||
coins.addOutput(index, undo.toOutput());
|
coins.addOutput(index, undo.toOutput());
|
||||||
|
|
||||||
assert(coins.has(index));
|
assert(coins.has(index));
|
||||||
|
|
||||||
return coins.getCoin(index);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -406,7 +406,7 @@ Mempool.prototype.getCoin = function getCoin(hash, index) {
|
|||||||
if (index >= entry.tx.outputs.length)
|
if (index >= entry.tx.outputs.length)
|
||||||
return;
|
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())
|
if (output.script.isUnspendable())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
coin = Coin.fromTX(tx, i);
|
coin = Coin.fromTX(tx, i, entry.height);
|
||||||
|
|
||||||
this.coinIndex.addCoin(coin);
|
this.coinIndex.addCoin(coin);
|
||||||
}
|
}
|
||||||
@ -1610,7 +1610,7 @@ Mempool.prototype.untrackEntry = function untrackEntry(entry) {
|
|||||||
if (output.script.isUnspendable())
|
if (output.script.isUnspendable())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
coin = Coin.fromTX(tx, i);
|
coin = Coin.fromTX(tx, i, entry.height);
|
||||||
|
|
||||||
this.coinIndex.removeCoin(coin);
|
this.coinIndex.removeCoin(coin);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -606,7 +606,17 @@ Block.prototype.getPrevout = function getPrevout() {
|
|||||||
* @returns {Object}
|
* @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');
|
var commitmentHash = this.getCommitmentHash('hex');
|
||||||
return {
|
return {
|
||||||
hash: this.rhash(),
|
hash: this.rhash(),
|
||||||
|
|||||||
@ -282,11 +282,12 @@ Coin.fromRaw = function fromRaw(data, enc) {
|
|||||||
* @param {Number} index
|
* @param {Number} index
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Coin.prototype.fromTX = function fromTX(tx, index) {
|
Coin.prototype.fromTX = function fromTX(tx, index, height) {
|
||||||
assert(util.isNumber(index));
|
assert(util.isNumber(index));
|
||||||
assert(index < tx.outputs.length);
|
assert(index < tx.outputs.length);
|
||||||
|
assert(typeof height === 'number');
|
||||||
this.version = tx.version;
|
this.version = tx.version;
|
||||||
this.height = tx.height;
|
this.height = height;
|
||||||
this.value = tx.outputs[index].value;
|
this.value = tx.outputs[index].value;
|
||||||
this.script = tx.outputs[index].script;
|
this.script = tx.outputs[index].script;
|
||||||
this.coinbase = tx.isCoinbase();
|
this.coinbase = tx.isCoinbase();
|
||||||
@ -302,8 +303,8 @@ Coin.prototype.fromTX = function fromTX(tx, index) {
|
|||||||
* @returns {Coin}
|
* @returns {Coin}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Coin.fromTX = function fromTX(tx, index) {
|
Coin.fromTX = function fromTX(tx, index, height) {
|
||||||
return new Coin().fromTX(tx, index);
|
return new Coin().fromTX(tx, index, height);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -224,7 +224,16 @@ Input.prototype.isCoinbase = function isCoinbase() {
|
|||||||
* @returns {Object}
|
* @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 {
|
return {
|
||||||
type: this.getType(coin),
|
type: this.getType(coin),
|
||||||
subtype: this.getSubtype(coin),
|
subtype: this.getSubtype(coin),
|
||||||
|
|||||||
@ -164,7 +164,7 @@ MTX.prototype.addInput = function addInput(coin, index) {
|
|||||||
|
|
||||||
if (coin instanceof TX) {
|
if (coin instanceof TX) {
|
||||||
input.fromTX(coin, index);
|
input.fromTX(coin, index);
|
||||||
coin = Coin.fromTX(coin, index);
|
coin = Coin.fromTX(coin, index, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (coin instanceof Coin) {
|
if (coin instanceof Coin) {
|
||||||
@ -1329,6 +1329,15 @@ MTX.prototype._mutable = function _mutable() {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
MTX.prototype.inspect = function inspect() {
|
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);
|
return TX.prototype.inspect.call(this, this.view);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -2001,7 +2001,17 @@ TX.prototype.toInv = function toInv() {
|
|||||||
* @returns {Object}
|
* @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 rate = 0;
|
||||||
var fee = 0;
|
var fee = 0;
|
||||||
|
|
||||||
|
|||||||
@ -439,7 +439,7 @@ TXDB.prototype.resolveOutputs = co(function* resolveOutputs(tx, block, resolved)
|
|||||||
var flags = constants.flags.MANDATORY_VERIFY_FLAGS;
|
var flags = constants.flags.MANDATORY_VERIFY_FLAGS;
|
||||||
var hash = tx.hash('hex');
|
var hash = tx.hash('hex');
|
||||||
var i, j, input, output, key;
|
var i, j, input, output, key;
|
||||||
var orphans, orphan, coin, valid;
|
var orphans, orphan, valid;
|
||||||
|
|
||||||
if (!resolved)
|
if (!resolved)
|
||||||
resolved = [];
|
resolved = [];
|
||||||
@ -460,8 +460,6 @@ TXDB.prototype.resolveOutputs = co(function* resolveOutputs(tx, block, resolved)
|
|||||||
|
|
||||||
delete this.orphans[key];
|
delete this.orphans[key];
|
||||||
|
|
||||||
coin = Coin.fromTX(tx, i);
|
|
||||||
|
|
||||||
// Note that their might be multiple
|
// Note that their might be multiple
|
||||||
// orphans per input, either due to
|
// orphans per input, either due to
|
||||||
// double spends or an adversary
|
// double spends or an adversary
|
||||||
@ -479,7 +477,7 @@ TXDB.prototype.resolveOutputs = co(function* resolveOutputs(tx, block, resolved)
|
|||||||
|
|
||||||
// We can finally verify this input.
|
// We can finally verify this input.
|
||||||
if (this.options.verify && orphan.tx.height === -1)
|
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,
|
// If it's valid and fully resolved,
|
||||||
// we can resolve _its_ outputs.
|
// we can resolve _its_ outputs.
|
||||||
@ -613,7 +611,7 @@ TXDB.prototype.resolveInput = co(function* resolveInput(tx, index, path) {
|
|||||||
assert(stx);
|
assert(stx);
|
||||||
|
|
||||||
// Crete the credit and add the undo coin.
|
// 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);
|
this.spendCredit(credit, stx, spent.index);
|
||||||
|
|
||||||
@ -1111,7 +1109,7 @@ TXDB.prototype.insert = co(function* insert(tx, block) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
credit = Credit.fromTX(tx, i);
|
credit = Credit.fromTX(tx, i, tx.height);
|
||||||
|
|
||||||
this.pending.coin++;
|
this.pending.coin++;
|
||||||
this.pending.unconfirmed += output.value;
|
this.pending.unconfirmed += output.value;
|
||||||
@ -1426,7 +1424,7 @@ TXDB.prototype.erase = co(function* erase(tx) {
|
|||||||
|
|
||||||
details.setOutput(i, path);
|
details.setOutput(i, path);
|
||||||
|
|
||||||
credit = Credit.fromTX(tx, i);
|
credit = Credit.fromTX(tx, i, tx.height);
|
||||||
|
|
||||||
this.pending.coin--;
|
this.pending.coin--;
|
||||||
this.pending.unconfirmed -= output.value;
|
this.pending.unconfirmed -= output.value;
|
||||||
@ -2981,8 +2979,8 @@ Credit.prototype.toRaw = function toRaw() {
|
|||||||
* @returns {Credit}
|
* @returns {Credit}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Credit.prototype.fromTX = function fromTX(tx, index) {
|
Credit.prototype.fromTX = function fromTX(tx, index, height) {
|
||||||
this.coin.fromTX(tx, index);
|
this.coin.fromTX(tx, index, height);
|
||||||
this.spent = false;
|
this.spent = false;
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
@ -2994,8 +2992,8 @@ Credit.prototype.fromTX = function fromTX(tx, index) {
|
|||||||
* @returns {Credit}
|
* @returns {Credit}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Credit.fromTX = function fromTX(tx, index) {
|
Credit.fromTX = function fromTX(tx, index, height) {
|
||||||
return new Credit().fromTX(tx, index);
|
return new Credit().fromTX(tx, index, height);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -225,7 +225,7 @@ describe('Chain', function() {
|
|||||||
yield chain.add(block);
|
yield chain.add(block);
|
||||||
|
|
||||||
tx = block.txs[1];
|
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);
|
coin = yield chain.db.getCoin(tx.hash('hex'), 1);
|
||||||
|
|
||||||
|
|||||||
@ -58,7 +58,7 @@ describe('Mempool', function() {
|
|||||||
|
|
||||||
mempool.trackEntry(entry, funding.view);
|
mempool.trackEntry(entry, funding.view);
|
||||||
|
|
||||||
return bcoin.coin.fromTX(funding, 0);
|
return bcoin.coin.fromTX(funding, 0, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
it('should open mempool', cob(function* () {
|
it('should open mempool', cob(function* () {
|
||||||
|
|||||||
@ -216,7 +216,7 @@ describe('Wallet', function() {
|
|||||||
.addOutput(w.getAddress(), 24000)
|
.addOutput(w.getAddress(), 24000)
|
||||||
.addOutput(w.getAddress(), 24000);
|
.addOutput(w.getAddress(), 24000);
|
||||||
|
|
||||||
doubleSpend = bcoin.coin.fromTX(t1, 0);
|
doubleSpend = bcoin.coin.fromTX(t1, 0, -1);
|
||||||
|
|
||||||
// balance: 49000
|
// balance: 49000
|
||||||
yield w.sign(t2);
|
yield w.sign(t2);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user