mempool/chain: move some methods around.

This commit is contained in:
Christopher Jeffrey 2016-12-08 15:51:25 -08:00
parent 2715e71ae8
commit d4c2331a11
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
3 changed files with 159 additions and 264 deletions

View File

@ -973,14 +973,15 @@ ChainDB.prototype.getFullBlock = co(function* getFullBlock(hash) {
/**
* Fill a transaction with coins (only unspents).
* @param {TX} tx
* @returns {Promise} - Returns {@link TX}.
* @returns {Promise}
*/
ChainDB.prototype.fillCoins = co(function* fillCoins(tx) {
var found = true;
var i, input, prevout, coin;
if (tx.isCoinbase())
return;
return found;
for (i = 0; i < tx.inputs.length; i++) {
input = tx.inputs[i];
@ -991,27 +992,33 @@ ChainDB.prototype.fillCoins = co(function* fillCoins(tx) {
coin = yield this.getCoin(prevout.hash, prevout.index);
if (!coin)
if (!coin) {
input.coin = null;
found = false;
continue;
}
input.coin = coin;
}
return found;
});
/**
* Fill a transaction with coins (all historical coins).
* @param {TX} tx
* @returns {Promise} - Returns {@link TX}.
* @returns {Promise}
*/
ChainDB.prototype.fillHistory = co(function* fillHistory(tx) {
var found = true;
var i, input, prevout, prev;
if (!this.options.indexTX)
return;
return found;
if (tx.isCoinbase())
return;
return found;
for (i = 0; i < tx.inputs.length; i++) {
input = tx.inputs[i];
@ -1022,14 +1029,16 @@ ChainDB.prototype.fillHistory = co(function* fillHistory(tx) {
prev = yield this.getTX(prevout.hash);
if (!prev)
continue;
if (prevout.index >= prev.outputs.length)
if (!prev || prevout.index >= prev.outputs.length) {
input.coin = null;
found = false;
continue;
}
input.coin = Coin.fromTX(prev, prevout.index);
}
return found;
});
/**

View File

@ -290,7 +290,7 @@ Mempool.prototype._reset = function reset() {
* @returns {Promise}
*/
Mempool.prototype.limitMempoolSize = function limitMempoolSize(entryHash) {
Mempool.prototype.limitSize = function limitSize(entryHash) {
var trimmed = false;
var i, hashes, hash, end, entry;
@ -717,7 +717,7 @@ Mempool.prototype._addTX = co(function* _addTX(tx) {
yield this.addEntry(entry);
// Trim size if we're too big.
if (this.limitMempoolSize(hash)) {
if (this.limitSize(hash)) {
throw new VerifyError(tx,
'insufficientfee',
'mempool full',
@ -911,9 +911,9 @@ Mempool.prototype.verify = co(function* verify(entry) {
// Script verification.
try {
yield this.verifyInputs(tx, flags1);
} catch (error) {
} catch (err) {
if (tx.hasWitness())
throw error;
throw err;
// Try without segwit and cleanstack.
result = yield this.verifyResult(tx, flags2);
@ -921,7 +921,7 @@ Mempool.prototype.verify = co(function* verify(entry) {
// If it failed, the first verification
// was the only result we needed.
if (!result)
throw error;
throw err;
// If it succeeded, segwit may be causing the
// failure. Try with segwit but without cleanstack.
@ -929,11 +929,11 @@ Mempool.prototype.verify = co(function* verify(entry) {
// Cleanstack was causing the failure.
if (result)
throw error;
throw err;
// Do not insert into reject cache.
error.malleated = true;
throw error;
err.malleated = true;
throw err;
}
// Paranoid checks.
@ -1313,89 +1313,6 @@ Mempool.prototype.storeOrphan = function storeOrphan(tx, missing) {
return true;
};
/**
* Spend coins for transaction.
* @param {TX} tx
* @returns {Boolean}
*/
Mempool.prototype.injectCoins = function injectCoins(tx, view) {
var missing = [];
var i, input, prevout, coin;
for (i = 0; i < tx.inputs.length; i++) {
input = tx.inputs[i];
prevout = input.prevout;
coin = view.getCoin(prevout.hash, prevout.index);
if (!coin) {
missing.push(prevout.hash);
continue;
}
input.coin = coin;
}
return missing;
};
/**
* Store an orphaned transaction.
* @param {TX} tx
*/
Mempool.prototype.maybeStoreOrphan = function maybeStoreOrphan(tx) {
var missing = {};
var i, hash, input, prev;
if (tx.getWeight() > constants.tx.MAX_WEIGHT) {
this.logger.debug('Ignoring large orphan: %s', tx.txid());
if (!tx.hasWitness())
this.rejects.add(tx.hash());
return;
}
for (i = 0; i < tx.inputs.length; i++) {
input = tx.inputs[i];
if (input.coin)
continue;
if (this.hasReject(input.prevout.hash)) {
this.logger.debug('Not storing orphan %s (rejected parents).', tx.txid());
this.rejects.add(tx.hash());
return;
}
missing[input.prevout.hash] = true;
}
hash = tx.hash('hex');
missing = Object.keys(missing);
assert(missing.length > 0);
for (i = 0; i < missing.length; i++) {
prev = missing[i];
if (!this.waiting[prev])
this.waiting[prev] = [];
this.waiting[prev].push(hash);
}
this.orphans[hash] = new Orphan(tx, missing.length);
this.totalOrphans++;
this.logger.debug('Added orphan %s to mempool.', tx.txid());
this.emit('add orphan', tx);
this.limitOrphans();
return missing;
};
/**
* Potentially resolve any transactions
* that redeem the passed-in transaction.
@ -1521,165 +1438,6 @@ Mempool.prototype.isDoubleSpend = function isDoubleSpend(tx) {
return false;
};
/**
* Fill a transaction with all available transaction outputs
* in the mempool. This differs from {@link Mempool#fillCoins}
* in that it will fill with all historical coins and not
* just unspent coins.
* @param {TX} tx
*/
Mempool.prototype.fillHistory = function fillHistory(tx) {
var found = true;
var i, input, prevout, prev;
if (tx.isCoinbase())
return false;
for (i = 0; i < tx.inputs.length; i++) {
input = tx.inputs[i];
prevout = input.prevout;
prev = this.getTX(prevout.hash);
if (!prev) {
input.coin = null;
found = false;
continue;
}
if (prevout.index >= prev.outputs.length) {
input.coin = null;
found = false;
continue;
}
input.coin = Coin.fromTX(prev, prevout.index);
}
return found;
};
/**
* Fill a transaction with all available (unspent) coins
* in the mempool.
* @param {TX} tx
*/
Mempool.prototype.fillCoins = function fillCoins(tx) {
var found = true;
var i, input, prevout, coin;
if (tx.isCoinbase())
return false;
for (i = 0; i < tx.inputs.length; i++) {
input = tx.inputs[i];
prevout = input.prevout;
coin = this.getCoin(prevout.hash, prevout.index);
if (!coin) {
input.coin = null;
found = false;
continue;
}
input.coin = coin;
}
return found;
};
/**
* Fill transaction with all unspent _and spent_
* coins. Similar to {@link Mempool#fillHistory}
* except that it will also fill with coins
* from the blockchain as well.
* @param {TX} tx
* @returns {Promise} - Returns {@link TX}.
*/
Mempool.prototype.fillAllHistory = function fillAllHistory(tx) {
this.fillHistory(tx);
if (tx.hasCoins())
return Promise.resolve(tx);
return this.chain.db.fillHistory(tx);
};
/**
* Fill transaction with all unspent
* coins. Similar to {@link Mempool#fillCoins}
* except that it will also fill with coins
* from the blockchain as well.
* @param {TX} tx
* @returns {Promise} - Returns {@link TX}.
*/
Mempool.prototype.fillAllCoins = co(function* fillAllCoins(tx) {
var found = true;
var i, input, hash, index, coin;
for (i = 0; i < tx.inputs.length; i++) {
input = tx.inputs[i];
hash = input.prevout.hash;
index = input.prevout.index;
coin = this.getCoin(hash, index);
if (coin) {
input.coin = coin;
continue;
}
if (this.isSpent(hash, index)) {
input.coin = null;
found = false;
continue;
}
coin = yield this.chain.db.getCoin(hash, index);
if (!coin) {
input.coin = null;
found = false;
continue;
}
input.coin = coin;
}
return found;
});
/**
* Get coin viewpoint.
* @param {TX} tx
* @returns {Promise} - Returns {@link CoinView}.
*/
Mempool.prototype.getCoinViewSlow = co(function* getCoinViewSlow(tx) {
var view = yield this.chain.db.getCoinView(tx);
var entries = view.toArray();
var i, coins, entry;
for (i = 0; i < entries.length; i++) {
coins = entries[i];
if (!coins.isEmpty())
continue;
entry = this.getEntry(coins.hash);
if (!entry)
continue;
view.addTX(entry.tx, -1);
}
return view;
});
/**
* Get coin viewpoint.
* @param {TX} tx
@ -1715,6 +1473,32 @@ Mempool.prototype.getCoinView = co(function* getCoinView(tx) {
return view;
});
/**
* Spend coins for transaction.
* @param {TX} tx
* @returns {Boolean}
*/
Mempool.prototype.injectCoins = function injectCoins(tx, view) {
var missing = [];
var i, input, prevout, coin;
for (i = 0; i < tx.inputs.length; i++) {
input = tx.inputs[i];
prevout = input.prevout;
coin = view.getCoin(prevout.hash, prevout.index);
if (!coin) {
missing.push(prevout.hash);
continue;
}
input.coin = coin;
}
return missing;
};
/**
* Get a snapshot of all transaction hashes in the mempool. Used
* for generating INV packets in response to MEMPOOL packets.
@ -1960,6 +1744,106 @@ Mempool.prototype.getSize = function getSize() {
return this.size;
};
/**
* Fill transaction with all unspent _and spent_
* coins. Similar to {@link Mempool#fillHistory}
* except that it will also fill with coins
* from the blockchain as well.
* @param {TX} tx
* @returns {Promise} - Returns {@link TX}.
*/
Mempool.prototype.fillHistory = co(function* fillHistory(tx) {
var found = true;
var i, input, prevout, prev;
if (tx.isCoinbase())
return found;
for (i = 0; i < tx.inputs.length; i++) {
input = tx.inputs[i];
prevout = input.prevout;
if (input.coin)
continue;
prev = this.getTX(prevout.hash);
if (prev) {
if (prevout.index >= prev.outputs.length) {
input.coin = null;
found = false;
continue;
}
input.coin = Coin.fromTX(prev, prevout.index);
continue;
}
prev = yield this.chain.db.getTX(prevout.hash);
if (!prev || prevout.index >= prev.outputs.length) {
input.coin = null;
found = false;
continue;
}
input.coin = Coin.fromTX(prev, prevout.index);
}
return found;
});
/**
* Fill transaction with all unspent
* coins. Similar to {@link Mempool#fillCoins}
* except that it will also fill with coins
* from the blockchain as well.
* @param {TX} tx
* @returns {Promise} - Returns {@link TX}.
*/
Mempool.prototype.fillCoins = co(function* fillCoins(tx) {
var found = true;
var i, input, hash, index, coin;
if (tx.isCoinbase())
return found;
for (i = 0; i < tx.inputs.length; i++) {
input = tx.inputs[i];
hash = input.prevout.hash;
index = input.prevout.index;
if (input.coin)
continue;
coin = this.getCoin(hash, index);
if (coin) {
input.coin = coin;
continue;
}
if (this.isSpent(hash, index)) {
input.coin = null;
found = false;
continue;
}
coin = yield this.chain.db.getCoin(hash, index);
if (!coin) {
input.coin = null;
found = false;
continue;
}
input.coin = coin;
}
return found;
});
/**
* Address Index
*/

View File

@ -422,8 +422,10 @@ FullNode.prototype.getCoinsByAddress = co(function* getCoinsByAddress(addresses)
coin = blockCoins[i];
spent = this.mempool.isSpent(coin.hash, coin.index);
if (!spent)
coins.push(coin);
if (spent)
continue;
coins.push(coin);
}
return coins;
@ -492,7 +494,7 @@ FullNode.prototype.isSpent = function isSpent(hash, index) {
*/
FullNode.prototype.fillCoins = function fillCoins(tx) {
return this.mempool.fillAllCoins(tx);
return this.mempool.fillCoins(tx);
};
/**
@ -503,7 +505,7 @@ FullNode.prototype.fillCoins = function fillCoins(tx) {
*/
FullNode.prototype.fillHistory = function fillHistory(tx) {
return this.mempool.fillAllHistory(tx);
return this.mempool.fillHistory(tx);
};
/*