mempool: refactor verification.
This commit is contained in:
parent
42f0b2aa19
commit
01f21b0399
@ -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
|
||||||
|
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user