tx/mempool: simplify some witness policy.
This commit is contained in:
parent
7688d80e74
commit
33bda01d21
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user