refactor script testing.

This commit is contained in:
Christopher Jeffrey 2016-07-01 15:09:33 -07:00
parent 87a94639d4
commit 745e89131c
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
5 changed files with 72 additions and 63 deletions

View File

@ -250,14 +250,14 @@ Address.prototype.fromScript = function fromScript(script) {
} }
// Fast case // Fast case
if (script.isPubkey()) { if (script.isPubkey(true)) {
this.hash = utils.hash160(script.raw.slice(1, script.raw[0] + 1)); this.hash = utils.hash160(script.raw.slice(1, script.raw[0] + 1));
this.type = 'pubkeyhash'; this.type = 'pubkeyhash';
this.version = -1; this.version = -1;
return this; return this;
} }
if (script.isPubkeyhash()) { if (script.isPubkeyhash(true)) {
this.hash = script.raw.slice(3, 23); this.hash = script.raw.slice(3, 23);
this.type = 'pubkeyhash'; this.type = 'pubkeyhash';
this.version = -1; this.version = -1;
@ -272,14 +272,14 @@ Address.prototype.fromScript = function fromScript(script) {
} }
// Slow case (allow non-minimal data and parse script) // Slow case (allow non-minimal data and parse script)
if (script.isPubkey(true)) { if (script.isPubkey()) {
this.hash = utils.hash160(script.code[0].data); this.hash = utils.hash160(script.code[0].data);
this.type = 'pubkeyhash'; this.type = 'pubkeyhash';
this.version = -1; this.version = -1;
return this; return this;
} }
if (script.isPubkeyhash(true)) { if (script.isPubkeyhash()) {
this.hash = script.code[2].data; this.hash = script.code[2].data;
this.type = 'pubkeyhash'; this.type = 'pubkeyhash';
this.version = -1; this.version = -1;

View File

@ -193,7 +193,7 @@ Coins.prototype.toRaw = function toRaw(writer) {
prefix = 0; prefix = 0;
// Saves up to 7 bytes. // Saves up to 7 bytes.
if (output.script.isPubkeyhash()) { if (output.script.isPubkeyhash(true)) {
prefix = 1; prefix = 1;
hash = output.script.code[2].data; hash = output.script.code[2].data;
} else if (output.script.isScripthash()) { } else if (output.script.isScripthash()) {

View File

@ -300,7 +300,7 @@ MTX.prototype.scriptInput = function scriptInput(index, addr) {
vector = input.script; vector = input.script;
} }
if (prev.isPubkey(true)) { if (prev.isPubkey()) {
// P2PK // P2PK
if (!utils.equal(prev.get(1), addr.publicKey)) if (!utils.equal(prev.get(1), addr.publicKey))
return false; return false;
@ -310,7 +310,7 @@ MTX.prototype.scriptInput = function scriptInput(index, addr) {
return true; return true;
vector.set(0, opcodes.OP_0); vector.set(0, opcodes.OP_0);
} else if (prev.isPubkeyhash(true)) { } else if (prev.isPubkeyhash()) {
// P2PKH // P2PKH
if (!utils.equal(prev.get(2), addr.keyHash)) if (!utils.equal(prev.get(2), addr.keyHash))
return false; return false;
@ -474,7 +474,7 @@ MTX.prototype.signInput = function signInput(index, addr, key, type) {
signature = this.createSignature(index, prev, key, type, version); signature = this.createSignature(index, prev, key, type, version);
// P2PK // P2PK
if (prev.isPubkey(true)) { if (prev.isPubkey()) {
// Already signed. // Already signed.
if (Script.isSignature(vector.get(0))) if (Script.isSignature(vector.get(0)))
return true; return true;
@ -493,7 +493,7 @@ MTX.prototype.signInput = function signInput(index, addr, key, type) {
} }
// P2PKH // P2PKH
if (prev.isPubkeyhash(true)) { if (prev.isPubkeyhash()) {
// Already signed. // Already signed.
if (Script.isSignature(vector.get(0))) if (Script.isSignature(vector.get(0)))
return true; return true;
@ -673,10 +673,10 @@ MTX.prototype.isSigned = function isSigned() {
len = vector.length; len = vector.length;
} }
if (prev.isPubkey(true)) { if (prev.isPubkey()) {
if (!Script.isSignature(vector.get(0))) if (!Script.isSignature(vector.get(0)))
return false; return false;
} else if (prev.isPubkeyhash(true)) { } else if (prev.isPubkeyhash()) {
if (!Script.isSignature(vector.get(0))) if (!Script.isSignature(vector.get(0)))
return false; return false;
} else if (prev.isMultisig()) { } else if (prev.isMultisig()) {
@ -883,11 +883,11 @@ MTX.prototype.maxSize = function maxSize(options, force) {
} }
} }
if (prev.isPubkey(true)) { if (prev.isPubkey()) {
// P2PK // P2PK
// OP_PUSHDATA0 [signature] // OP_PUSHDATA0 [signature]
size += 1 + 73; size += 1 + 73;
} else if (prev.isPubkeyhash(true)) { } else if (prev.isPubkeyhash()) {
// P2PKH // P2PKH
// OP_PUSHDATA0 [signature] // OP_PUSHDATA0 [signature]
size += 1 + 73; size += 1 + 73;

View File

@ -2827,53 +2827,54 @@ Script.prototype.getAddress = function getAddress() {
/** /**
* Test whether the output script is pay-to-pubkey. * Test whether the output script is pay-to-pubkey.
* @param {Boolean} [sloppy=false] - Allow non-minimal scripts. * @param {Boolean} [minimal=false] - Minimaldata only.
* @returns {Boolean} * @returns {Boolean}
*/ */
Script.prototype.isPubkey = function isPubkey(sloppy) { Script.prototype.isPubkey = function isPubkey(minimal) {
if (sloppy) { if (minimal) {
return this.code.length === 2 return this.raw[0] >= 33 && this.raw[0] <= 65
&& Script.isKey(this.code[0].data) && this.raw[0] + 2 === this.raw.length
&& this.code[1].value === opcodes.OP_CHECKSIG; && this.raw[this.raw.length - 1] === opcodes.OP_CHECKSIG;
} }
return this.raw[0] >= 33 && this.raw[0] <= 65 return this.code.length === 2
&& this.raw[0] + 2 === this.raw.length && Script.isKey(this.code[0].data)
&& this.raw[this.raw.length - 1] === opcodes.OP_CHECKSIG; && this.code[1].value === opcodes.OP_CHECKSIG;
}; };
/** /**
* Test whether the output script is pay-to-pubkeyhash. * Test whether the output script is pay-to-pubkeyhash.
* @param {Boolean} [sloppy=false] - Allow non-minimal scripts. * @param {Boolean} [minimal=false] - Minimaldata only.
* @returns {Boolean} * @returns {Boolean}
*/ */
Script.prototype.isPubkeyhash = function isPubkeyhash(sloppy) { Script.prototype.isPubkeyhash = function isPubkeyhash(minimal) {
if (sloppy) { if (!minimal) {
return this.code.length === 5 return this.raw.length === 25
&& this.code[0].value === opcodes.OP_DUP && this.raw[0] === opcodes.OP_DUP
&& this.code[1].value === opcodes.OP_HASH160 && this.raw[1] === opcodes.OP_HASH160
&& Script.isHash(this.code[2].data) && this.raw[2] === 0x14
&& this.code[3].value === opcodes.OP_EQUALVERIFY && this.raw[23] === opcodes.OP_EQUALVERIFY
&& this.code[4].value === opcodes.OP_CHECKSIG; && this.raw[24] === opcodes.OP_CHECKSIG;
} }
return this.raw.length === 25 return this.code.length === 5
&& this.raw[0] === opcodes.OP_DUP && this.code[0].value === opcodes.OP_DUP
&& this.raw[1] === opcodes.OP_HASH160 && this.code[1].value === opcodes.OP_HASH160
&& this.raw[2] === 0x14 && Script.isHash(this.code[2].data)
&& this.raw[23] === opcodes.OP_EQUALVERIFY && this.code[3].value === opcodes.OP_EQUALVERIFY
&& this.raw[24] === opcodes.OP_CHECKSIG; && this.code[4].value === opcodes.OP_CHECKSIG;
}; };
/** /**
* Test whether the output script is pay-to-multisig. * Test whether the output script is pay-to-multisig.
* @param {Boolean} [minimal=false] - Minimaldata only.
* @returns {Boolean} * @returns {Boolean}
*/ */
Script.prototype.isMultisig = function isMultisig() { Script.prototype.isMultisig = function isMultisig(minimal) {
var m, n, i; var m, n, i, op;
if (this.raw.length < 41) if (this.raw.length < 41)
return false; return false;
@ -2895,8 +2896,15 @@ Script.prototype.isMultisig = function isMultisig() {
return false; return false;
for (i = 1; i < n + 1; i++) { for (i = 1; i < n + 1; i++) {
if (!Script.isKey(this.code[i].data)) op = this.code[i];
if (!Script.isKey(op.data))
return false; return false;
if (minimal) {
if (!Script.isMinimal(op.data, op.value))
return false;
}
} }
return true; return true;
@ -2919,11 +2927,11 @@ Script.prototype.isScripthash = function isScripthash() {
/** /**
* Test whether the output script is nulldata/opreturn. * Test whether the output script is nulldata/opreturn.
* @param {Boolean} [sloppy=false] - Allow non-minimal scripts. * @param {Boolean} [minimal=false] - Minimaldata only.
* @returns {Boolean} * @returns {Boolean}
*/ */
Script.prototype.isNulldata = function isNulldata(sloppy) { Script.prototype.isNulldata = function isNulldata(minimal) {
var i, op; var i, op;
if (this.raw.length > constants.script.MAX_OP_RETURN_BYTES) if (this.raw.length > constants.script.MAX_OP_RETURN_BYTES)
@ -2938,29 +2946,30 @@ Script.prototype.isNulldata = function isNulldata(sloppy) {
if (this.raw.length === 1) if (this.raw.length === 1)
return true; return true;
if (sloppy) { if (minimal) {
for (i = 1; i < this.code.length; i++) { if (this.raw.length === 2)
op = this.code[i]; return Script.getSmall(this.raw[1]) !== -1;
if (op.data)
continue; if (this.raw[1] >= 0x01 && this.raw[1] <= 0x4b)
if (op.value === -1) return this.raw[1] + 2 === this.raw.length;
return false;
if (op.value > opcodes.OP_16) if (this.raw[1] === opcodes.OP_PUSHDATA1)
return false; return this.raw[2] > 75 && this.raw[2] + 3 === this.raw.length;
}
return true; return false;
} }
if (this.raw.length === 2) for (i = 1; i < this.code.length; i++) {
return Script.getSmall(this.raw[1]) !== -1; op = this.code[i];
if (op.data)
continue;
if (op.value === -1)
return false;
if (op.value > opcodes.OP_16)
return false;
}
if (this.raw[1] >= 0x01 && this.raw[1] <= 0x4b) return true;
return this.raw[1] + 2 === this.raw.length;
if (this.raw[1] === opcodes.OP_PUSHDATA1)
return this.raw[2] > 75 && this.raw[2] + 3 === this.raw.length;
return false;
}; };
/** /**

View File

@ -1735,7 +1735,7 @@ TX.prototype.isWatched = function isWatched(filter) {
outpoint = bcoin.outpoint.fromTX(this, i); outpoint = bcoin.outpoint.fromTX(this, i);
filter.add(outpoint.toRaw()); filter.add(outpoint.toRaw());
} else if (filter.update === constants.filterFlags.PUBKEY_ONLY) { } else if (filter.update === constants.filterFlags.PUBKEY_ONLY) {
if (output.script.isPubkey(true) || output.script.isMultisig()) { if (output.script.isPubkey() || output.script.isMultisig()) {
outpoint = bcoin.outpoint.fromTX(this, i); outpoint = bcoin.outpoint.fromTX(this, i);
filter.add(outpoint.toRaw()); filter.add(outpoint.toRaw());
} }