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,
|
throw new VerifyError(tx,
|
||||||
'nonstandard',
|
'nonstandard',
|
||||||
'no-witness-yet',
|
'no-witness-yet',
|
||||||
0);
|
0,
|
||||||
|
true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -803,12 +804,12 @@ Mempool.prototype.verify = co(function* verify(entry, view) {
|
|||||||
0);
|
0);
|
||||||
}
|
}
|
||||||
if (this.chain.state.hasWitness()) {
|
if (this.chain.state.hasWitness()) {
|
||||||
if (!tx.hasStandardWitness(view, ret)) {
|
if (!tx.hasStandardWitness(view)) {
|
||||||
throw new VerifyError(tx,
|
throw new VerifyError(tx,
|
||||||
'nonstandard',
|
'nonstandard',
|
||||||
ret.reason,
|
'bad-witness-nonstandard',
|
||||||
ret.score,
|
0,
|
||||||
ret.score > 0);
|
true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -27,15 +27,6 @@ var Bloom = require('../utils/bloom');
|
|||||||
var consensus = require('../protocol/consensus');
|
var consensus = require('../protocol/consensus');
|
||||||
var policy = require('../protocol/policy');
|
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.
|
* A static transaction object.
|
||||||
* @alias module:primitives.TX
|
* @alias module:primitives.TX
|
||||||
@ -1567,56 +1558,21 @@ TX.prototype.hasStandardInputs = function hasStandardInputs(view) {
|
|||||||
* @returns {Boolean}
|
* @returns {Boolean}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
TX.prototype.hasStandardWitness = function hasStandardWitness(view, ret) {
|
TX.prototype.hasStandardWitness = function hasStandardWitness(view) {
|
||||||
var result = this.getWitnessStandard(view);
|
var i, j, input, witness, coin, prev, redeem, m, n;
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
if (this.isCoinbase())
|
if (this.isCoinbase())
|
||||||
return ret;
|
return true;
|
||||||
|
|
||||||
for (i = 0; i < this.inputs.length; i++) {
|
for (i = 0; i < this.inputs.length; i++) {
|
||||||
input = this.inputs[i];
|
input = this.inputs[i];
|
||||||
|
witness = input.witness;
|
||||||
coin = view.getOutput(input);
|
coin = view.getOutput(input);
|
||||||
|
|
||||||
if (!coin)
|
if (!coin)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (input.witness.length === 0)
|
if (witness.items.length === 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
prev = coin.script;
|
prev = coin.script;
|
||||||
@ -1624,23 +1580,21 @@ TX.prototype.getWitnessStandard = function getWitnessStandard(view) {
|
|||||||
if (prev.isScripthash()) {
|
if (prev.isScripthash()) {
|
||||||
prev = input.script.getRedeem();
|
prev = input.script.getRedeem();
|
||||||
if (!prev)
|
if (!prev)
|
||||||
return BAD_P2SH;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!prev.isProgram())
|
if (!prev.isProgram())
|
||||||
return BAD_WITNESS;
|
return false;
|
||||||
|
|
||||||
if (prev.isWitnessPubkeyhash()) {
|
if (prev.isWitnessPubkeyhash()) {
|
||||||
if (input.witness.length !== 2)
|
if (witness.items.length !== 2)
|
||||||
return BAD_WITNESS;
|
return false;
|
||||||
|
|
||||||
if (input.witness.get(0).length > 73)
|
if (witness.items[0].length > 73)
|
||||||
return BAD_WITNESS;
|
return false;
|
||||||
|
|
||||||
hash = crypto.hash160(input.witness.get(1));
|
if (witness.items[1].length > 65)
|
||||||
|
return false;
|
||||||
if (!util.equal(hash, prev.get(1)))
|
|
||||||
return BAD_WITNESS;
|
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -1651,69 +1605,57 @@ TX.prototype.getWitnessStandard = function getWitnessStandard(view) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
redeem = input.witness.get(input.witness.length - 1);
|
redeem = witness.items[witness.items.length - 1];
|
||||||
|
|
||||||
if (redeem.length > consensus.MAX_SCRIPT_SIZE)
|
|
||||||
return BAD_WITNESS;
|
|
||||||
|
|
||||||
if (redeem.length > policy.MAX_P2WSH_SIZE)
|
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)))
|
for (j = 0; j < witness.items.length; j++) {
|
||||||
return BAD_WITNESS;
|
if (witness.items[j].length > policy.MAX_P2WSH_PUSH)
|
||||||
|
return false;
|
||||||
// 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
redeem = new Script(redeem);
|
prev = new Script(redeem);
|
||||||
|
|
||||||
if (redeem.isPubkey()) {
|
if (prev.isPubkey()) {
|
||||||
if (input.witness.length - 1 !== 1)
|
if (witness.items.length - 1 !== 1)
|
||||||
return BAD_WITNESS;
|
return false;
|
||||||
|
|
||||||
if (input.witness.get(0).length > 73)
|
if (witness.items[0].length > 73)
|
||||||
return BAD_WITNESS;
|
return false;
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (redeem.isPubkeyhash()) {
|
if (prev.isPubkeyhash()) {
|
||||||
if (input.witness.length - 1 !== 2)
|
if (input.witness.length - 1 !== 2)
|
||||||
return BAD_WITNESS;
|
return false;
|
||||||
|
|
||||||
if (input.witness.get(0).length > 73)
|
if (witness.items[0].length > 73)
|
||||||
return BAD_WITNESS;
|
return false;
|
||||||
|
|
||||||
|
if (witness.items[1].length > 65)
|
||||||
|
return false;
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (redeem.isMultisig()) {
|
if (prev.isMultisig()) {
|
||||||
m = redeem.getSmall(0);
|
m = prev.getSmall(0);
|
||||||
n = redeem.getSmall(redeem.length - 2);
|
n = prev.getSmall(prev.length - 2);
|
||||||
|
|
||||||
if (input.witness.length - 1 !== m + 1)
|
if (witness.items.length - 1 !== m + 1)
|
||||||
return BAD_WITNESS;
|
return false;
|
||||||
|
|
||||||
if (input.witness.get(0).length !== 0)
|
if (witness.items[0].length !== 0)
|
||||||
return BAD_WITNESS;
|
return false;
|
||||||
|
|
||||||
for (j = 1; j < input.witness.length - 1; j++) {
|
for (j = 1; j < witness.items.length - 1; j++) {
|
||||||
if (input.witness.get(i).length > 73)
|
if (witness.items[j].length > 73)
|
||||||
return BAD_WITNESS;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user