tx/mempool: simplify some witness policy.

This commit is contained in:
Christopher Jeffrey 2017-02-22 07:21:41 -08:00
parent 7688d80e74
commit 33bda01d21
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
2 changed files with 49 additions and 106 deletions

View File

@ -682,7 +682,8 @@ Mempool.prototype._addTX = co(function* _addTX(tx) {
throw new VerifyError(tx,
'nonstandard',
'no-witness-yet',
0);
0,
true);
}
}
@ -803,12 +804,12 @@ Mempool.prototype.verify = co(function* verify(entry, view) {
0);
}
if (this.chain.state.hasWitness()) {
if (!tx.hasStandardWitness(view, ret)) {
if (!tx.hasStandardWitness(view)) {
throw new VerifyError(tx,
'nonstandard',
ret.reason,
ret.score,
ret.score > 0);
'bad-witness-nonstandard',
0,
true);
}
}
}

View File

@ -27,15 +27,6 @@ var Bloom = require('../utils/bloom');
var consensus = require('../protocol/consensus');
var policy = require('../protocol/policy');
/*
* Constants
*/
var BAD_OKAY = 0;
var BAD_WITNESS = 1;
var BAD_P2SH = 2;
var BAD_NONSTD_P2WSH = 3;
/**
* A static transaction object.
* @alias module:primitives.TX
@ -1567,56 +1558,21 @@ TX.prototype.hasStandardInputs = function hasStandardInputs(view) {
* @returns {Boolean}
*/
TX.prototype.hasStandardWitness = function hasStandardWitness(view, ret) {
var result = this.getWitnessStandard(view);
if (!ret)
ret = new VerifyResult();
switch (result) {
case BAD_WITNESS:
ret.reason = 'bad-witness';
ret.score = 100;
return false;
case BAD_P2SH:
ret.reason = 'bad-P2SH-scriptSig';
ret.score = 100;
return false;
case BAD_NONSTD_P2WSH:
ret.reason = 'bad-witness-nonstandard';
ret.score = 0;
return false;
}
return true;
};
/**
* Perform contextual checks to verify coin and witness standardness.
* @private
* @see IsBadWitness()
* @param {CoinView} view
* @returns {Boolean}
*/
TX.prototype.getWitnessStandard = function getWitnessStandard(view) {
var ret = BAD_OKAY;
var i, j, input, prev, hash, redeem, m, n, coin;
if (!this.hasWitness())
return ret;
TX.prototype.hasStandardWitness = function hasStandardWitness(view) {
var i, j, input, witness, coin, prev, redeem, m, n;
if (this.isCoinbase())
return ret;
return true;
for (i = 0; i < this.inputs.length; i++) {
input = this.inputs[i];
witness = input.witness;
coin = view.getOutput(input);
if (!coin)
continue;
if (input.witness.length === 0)
if (witness.items.length === 0)
continue;
prev = coin.script;
@ -1624,23 +1580,21 @@ TX.prototype.getWitnessStandard = function getWitnessStandard(view) {
if (prev.isScripthash()) {
prev = input.script.getRedeem();
if (!prev)
return BAD_P2SH;
return false;
}
if (!prev.isProgram())
return BAD_WITNESS;
return false;
if (prev.isWitnessPubkeyhash()) {
if (input.witness.length !== 2)
return BAD_WITNESS;
if (witness.items.length !== 2)
return false;
if (input.witness.get(0).length > 73)
return BAD_WITNESS;
if (witness.items[0].length > 73)
return false;
hash = crypto.hash160(input.witness.get(1));
if (!util.equal(hash, prev.get(1)))
return BAD_WITNESS;
if (witness.items[1].length > 65)
return false;
continue;
}
@ -1651,69 +1605,57 @@ TX.prototype.getWitnessStandard = function getWitnessStandard(view) {
continue;
}
redeem = input.witness.get(input.witness.length - 1);
if (redeem.length > consensus.MAX_SCRIPT_SIZE)
return BAD_WITNESS;
redeem = witness.items[witness.items.length - 1];
if (redeem.length > policy.MAX_P2WSH_SIZE)
ret = BAD_NONSTD_P2WSH;
return false;
hash = crypto.sha256(redeem);
if (witness.items.length - 1 > policy.MAX_P2WSH_STACK)
return false;
if (!util.equal(hash, prev.get(1)))
return BAD_WITNESS;
// Based on Johnson Lau's calculations:
if (input.witness.length - 1 > 604)
return BAD_WITNESS;
if (input.witness.length - 1 > policy.MAX_P2WSH_STACK)
ret = BAD_NONSTD_P2WSH;
for (j = 0; j < input.witness.length; j++) {
if (input.witness.get(j).length > consensus.MAX_SCRIPT_PUSH)
return BAD_WITNESS;
if (input.witness.get(j).length > policy.MAX_P2WSH_PUSH)
ret = BAD_NONSTD_P2WSH;
for (j = 0; j < witness.items.length; j++) {
if (witness.items[j].length > policy.MAX_P2WSH_PUSH)
return false;
}
redeem = new Script(redeem);
prev = new Script(redeem);
if (redeem.isPubkey()) {
if (input.witness.length - 1 !== 1)
return BAD_WITNESS;
if (prev.isPubkey()) {
if (witness.items.length - 1 !== 1)
return false;
if (input.witness.get(0).length > 73)
return BAD_WITNESS;
if (witness.items[0].length > 73)
return false;
continue;
}
if (redeem.isPubkeyhash()) {
if (prev.isPubkeyhash()) {
if (input.witness.length - 1 !== 2)
return BAD_WITNESS;
return false;
if (input.witness.get(0).length > 73)
return BAD_WITNESS;
if (witness.items[0].length > 73)
return false;
if (witness.items[1].length > 65)
return false;
continue;
}
if (redeem.isMultisig()) {
m = redeem.getSmall(0);
n = redeem.getSmall(redeem.length - 2);
if (prev.isMultisig()) {
m = prev.getSmall(0);
n = prev.getSmall(prev.length - 2);
if (input.witness.length - 1 !== m + 1)
return BAD_WITNESS;
if (witness.items.length - 1 !== m + 1)
return false;
if (input.witness.get(0).length !== 0)
return BAD_WITNESS;
if (witness.items[0].length !== 0)
return false;
for (j = 1; j < input.witness.length - 1; j++) {
if (input.witness.get(i).length > 73)
return BAD_WITNESS;
for (j = 1; j < witness.items.length - 1; j++) {
if (witness.items[j].length > 73)
return false;
}
}
}