mempool: refactor verification.

This commit is contained in:
Christopher Jeffrey 2016-12-18 16:45:35 -08:00
parent 42f0b2aa19
commit 01f21b0399
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
2 changed files with 17 additions and 22 deletions

View File

@ -15,7 +15,6 @@ var crypto = require('../crypto/crypto');
var errors = require('../btc/errors'); var errors = require('../btc/errors');
var VerifyError = errors.VerifyError; var VerifyError = errors.VerifyError;
var VerifyResult = errors.VerifyResult; var VerifyResult = errors.VerifyResult;
var flags = constants.flags;
var Bloom = require('../utils/bloom'); var Bloom = require('../utils/bloom');
var Address = require('../primitives/address'); var Address = require('../primitives/address');
var Coin = require('../primitives/coin'); var Coin = require('../primitives/coin');
@ -799,14 +798,11 @@ Mempool.prototype._addTX = co(function* _addTX(tx) {
*/ */
Mempool.prototype.verify = co(function* verify(entry, view) { Mempool.prototype.verify = co(function* verify(entry, view) {
var tx = entry.tx;
var height = this.chain.height + 1; var height = this.chain.height + 1;
var lockFlags = flags.STANDARD_LOCKTIME_FLAGS; var lockFlags = constants.flags.STANDARD_LOCKTIME_FLAGS;
var flags1 = flags.STANDARD_VERIFY_FLAGS; var flags = constants.flags.STANDARD_VERIFY_FLAGS;
var flags2 = flags1 & ~(flags.VERIFY_WITNESS | flags.VERIFY_CLEANSTACK);
var flags3 = flags1 & ~flags.VERIFY_CLEANSTACK;
var mandatory = flags.MANDATORY_VERIFY_FLAGS;
var ret = new VerifyResult(); var ret = new VerifyResult();
var tx = entry.tx;
var now, minFee, result; var now, minFee, result;
// Verify sequence locks. // Verify sequence locks.
@ -838,7 +834,7 @@ Mempool.prototype.verify = co(function* verify(entry, view) {
} }
// Annoying process known as sigops counting. // Annoying process known as sigops counting.
if (tx.getSigopsCost(view, flags) > constants.tx.MAX_SIGOPS_COST) { if (entry.sigops > constants.tx.MAX_SIGOPS_COST) {
throw new VerifyError(tx, throw new VerifyError(tx,
'nonstandard', 'nonstandard',
'bad-txns-too-many-sigops', 'bad-txns-too-many-sigops',
@ -896,13 +892,15 @@ Mempool.prototype.verify = co(function* verify(entry, view) {
// Script verification. // Script verification.
try { try {
yield this.verifyInputs(tx, view, flags1); yield this.verifyInputs(tx, view, flags);
} catch (err) { } catch (err) {
if (tx.hasWitness()) if (tx.hasWitness())
throw err; throw err;
// Try without segwit and cleanstack. // Try without segwit and cleanstack.
result = yield this.verifyResult(tx, view, flags2); flags &= ~constants.flags.VERIFY_WITNESS;
flags &= ~constants.flags.VERIFY_CLEANSTACK;
result = yield this.verifyResult(tx, view, flags);
// If it failed, the first verification // If it failed, the first verification
// was the only result we needed. // was the only result we needed.
@ -911,7 +909,8 @@ Mempool.prototype.verify = co(function* verify(entry, view) {
// If it succeeded, segwit may be causing the // If it succeeded, segwit may be causing the
// failure. Try with segwit but without cleanstack. // failure. Try with segwit but without cleanstack.
result = yield this.verifyResult(tx, view, flags3); flags |= constants.flags.VERIFY_CLEANSTACK;
result = yield this.verifyResult(tx, view, flags);
// Cleanstack was causing the failure. // Cleanstack was causing the failure.
if (result) if (result)
@ -924,7 +923,8 @@ Mempool.prototype.verify = co(function* verify(entry, view) {
// Paranoid checks. // Paranoid checks.
if (this.paranoid) { if (this.paranoid) {
result = yield this.verifyResult(tx, view, mandatory); flags = constants.flags.MANDATORY_VERIFY_FLAGS;
result = yield this.verifyResult(tx, view, flags);
assert(result, 'BUG: Verify failed for mandatory but not standard.'); assert(result, 'BUG: Verify failed for mandatory but not standard.');
} }
}); });
@ -1632,7 +1632,7 @@ Mempool.prototype.verifyFinal = function verifyFinal(tx, flags) {
Mempool.prototype.trackEntry = function trackEntry(entry, view) { Mempool.prototype.trackEntry = function trackEntry(entry, view) {
var tx = entry.tx; var tx = entry.tx;
var hash = tx.hash('hex'); var hash = tx.hash('hex');
var i, input, output, key, coin; var i, input, output, key;
assert(!this.tx[hash]); assert(!this.tx[hash]);
this.tx[hash] = entry; this.tx[hash] = entry;
@ -1717,8 +1717,6 @@ Mempool.prototype.untrackEntry = function untrackEntry(entry) {
* Recursively remove spenders of a transaction. * Recursively remove spenders of a transaction.
* @private * @private
* @param {MempoolEntry} entry * @param {MempoolEntry} entry
* @param {Boolean} limit
* @returns {Promise}
*/ */
Mempool.prototype.removeSpenders = function removeSpenders(entry) { Mempool.prototype.removeSpenders = function removeSpenders(entry) {
@ -1740,9 +1738,7 @@ Mempool.prototype.removeSpenders = function removeSpenders(entry) {
* Recursively remove double spenders * Recursively remove double spenders
* of a mined transaction's outpoints. * of a mined transaction's outpoints.
* @private * @private
* @param {MempoolEntry} entry * @param {TX} tx
* @param {Boolean} limit
* @returns {Promise}
*/ */
Mempool.prototype.removeDoubleSpends = function removeDoubleSpends(tx) { Mempool.prototype.removeDoubleSpends = function removeDoubleSpends(tx) {
@ -1783,9 +1779,7 @@ Mempool.prototype.memUsage = function memUsage(tx) {
mem += 80; // _hash mem += 80; // _hash
mem += 88; // _hhash mem += 88; // _hhash
mem += 80; // _raw mem += 80; // _raw
mem += 80; // _whash
if (tx._whash)
mem += 80; // _whash
mem += 32; // input array mem += 32; // input array

View File

@ -82,9 +82,10 @@ MempoolEntry.fromOptions = function fromOptions(options) {
*/ */
MempoolEntry.prototype.fromTX = function fromTX(tx, view, height) { MempoolEntry.prototype.fromTX = function fromTX(tx, view, height) {
var flags = constants.flags.STANDARD_VERIFY_FLAGS;
var priority = tx.getPriority(view, height); var priority = tx.getPriority(view, height);
var value = tx.getChainValue(view, height); var value = tx.getChainValue(view, height);
var sigops = tx.getSigopsCost(view); var sigops = tx.getSigopsCost(view, flags);
var dependencies = false; var dependencies = false;
var size = tx.getVirtualSize(); var size = tx.getVirtualSize();
var fee = tx.getFee(view); var fee = tx.getFee(view);