script: remove mast.

This commit is contained in:
Christopher Jeffrey 2017-11-16 20:51:10 -08:00
parent 163e89fc29
commit 9b269dd1f0
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
4 changed files with 3 additions and 185 deletions

View File

@ -766,15 +766,6 @@ class Address {
return this.version === 0 && this.hash.length === 32;
}
/**
* Test whether the address is witness masthash.
* @returns {Boolean}
*/
isWitnessMasthash() {
return this.version === 1 && this.hash.length === 32;
}
/**
* Test whether the address is a witness program.
* @returns {Boolean}

View File

@ -346,8 +346,7 @@ exports.flags = {
VERIFY_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM: 1 << 12,
VERIFY_MINIMALIF: 1 << 13,
VERIFY_NULLFAIL: 1 << 14,
VERIFY_WITNESS_PUBKEYTYPE: 1 << 15,
VERIFY_MAST: 1 << 16
VERIFY_WITNESS_PUBKEYTYPE: 1 << 15
};
/**
@ -448,8 +447,7 @@ exports.types = {
NULLDATA: 5,
WITNESSMALFORMED: 0x80,
WITNESSSCRIPTHASH: 0x81,
WITNESSPUBKEYHASH: 0x82,
WITNESSMASTHASH: 0x83
WITNESSPUBKEYHASH: 0x82
};
/**
@ -466,8 +464,7 @@ exports.typesByVal = {
5: 'NULLDATA',
0x80: 'WITNESSMALFORMED',
0x81: 'WITNESSSCRIPTHASH',
0x82: 'WITNESSPUBKEYHASH',
0x83: 'WITNESSMASTHASH'
0x82: 'WITNESSPUBKEYHASH'
};
/**

View File

@ -54,14 +54,6 @@ class Program {
return scriptTypes.WITNESSMALFORMED;
}
if (this.version === 1) {
if (this.data.length === 32)
return scriptTypes.WITNESSMASTHASH;
// Fail on bad version=1
return scriptTypes.WITNESSMALFORMED;
}
// No interpretation of script (anyone can spend)
return scriptTypes.NONSTANDARD;
}

View File

@ -1724,9 +1724,6 @@ class Script {
if (this.isWitnessScripthash())
return scriptTypes.WITNESSSCRIPTHASH;
if (this.isWitnessMasthash())
return scriptTypes.WITNESSMASTHASH;
if (this.isMultisig())
return scriptTypes.MULTISIG;
@ -2187,30 +2184,6 @@ class Script {
return this.getData(1);
}
/**
* Test whether the output script
* is a pay-to-mast program.
* @returns {Boolean}
*/
isWitnessMasthash() {
return this.raw.length === 34
&& this.raw[0] === opcodes.OP_1
&& this.raw[1] === 0x20;
}
/**
* Get P2WMH hash if present.
* @returns {Buffer|null}
*/
getWitnessMasthash() {
if (!this.isWitnessMasthash())
return null;
return this.getData(1);
}
/**
* Test whether the output script is unspendable.
* @returns {Boolean}
@ -3256,9 +3229,6 @@ class Script {
// Failure on version=0 (bad program data length).
throw new ScriptError('WITNESS_PROGRAM_WRONG_LENGTH');
}
} else if ((flags & Script.flags.VERIFY_MAST) && program.version === 1) {
Script.verifyMast(program, stack, output, flags, tx, index);
return;
} else {
// Anyone can spend (we can return true here
// if we want to always relay these transactions).
@ -3286,138 +3256,6 @@ class Script {
throw new ScriptError('EVAL_FALSE');
}
/**
* Verify a MAST witness program.
* @param {Program} program
* @param {Stack} stack
* @param {Script} output
* @param {VerifyFlags} flags
* @param {TX} tx
* @param {Number} index
* @param {Amount} value
* @throws {ScriptError}
*/
static verifyMast(program, stack, output, flags, tx, index, value) {
assert(program.version === 1);
assert((flags & Script.flags.VERIFY_MAST) !== 0);
if (stack.length < 4)
throw new ScriptError('INVALID_MAST_STACK');
const metadata = stack.get(-1);
if (metadata.length < 1 || metadata.length > 5)
throw new ScriptError('INVALID_MAST_STACK');
const subscripts = metadata[0];
if (subscripts === 0 || stack.length < subscripts + 3)
throw new ScriptError('INVALID_MAST_STACK');
let ops = subscripts;
let scriptRoot = bio.write();
scriptRoot.writeU8(subscripts);
if (metadata[metadata.length - 1] === 0x00)
throw new ScriptError('INVALID_MAST_STACK');
let version = 0;
for (let j = 1; j < metadata.length; j++)
version |= metadata[j] << 8 * (j - 1);
if (version < 0)
version += 0x100000000;
if (version > 0) {
if (flags & Script.flags.DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM)
throw new ScriptError('DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM');
}
let mastRoot = bio.write();
mastRoot.writeU32(version);
const pathdata = stack.get(-2);
if (pathdata.length & 0x1f)
throw new ScriptError('INVALID_MAST_STACK');
const depth = pathdata.length >>> 5;
if (depth > 32)
throw new ScriptError('INVALID_MAST_STACK');
ops += depth;
if (version === 0) {
if (ops > consensus.MAX_SCRIPT_OPS)
throw new ScriptError('OP_COUNT');
}
const path = [];
for (let j = 0; j < depth; j++)
path.push(pathdata.slice(j * 32, j * 32 + 32));
const posdata = stack.get(-3);
if (posdata.length > 4)
throw new ScriptError('INVALID_MAST_STACK');
let pos = 0;
if (posdata.length > 0) {
if (posdata[posdata.length - 1] === 0x00)
throw new ScriptError('INVALID_MAST_STACK');
for (let j = 0; j < posdata.length; j++)
pos |= posdata[j] << 8 * j;
if (pos < 0)
pos += 0x100000000;
}
if (depth < 32) {
if (pos >= ((1 << depth) >>> 0))
throw new ScriptError('INVALID_MAST_STACK');
}
let scripts = bio.write();
scripts.writeBytes(output.raw);
for (let j = 0; j < subscripts; j++) {
const script = stack.get(-(4 + j));
if (version === 0) {
if ((scripts.offset + script.length) > consensus.MAX_SCRIPT_SIZE)
throw new ScriptError('SCRIPT_SIZE');
}
scriptRoot.writeBytes(hash256.digest(script));
scripts.writeBytes(script);
}
scriptRoot = hash256.digest(scriptRoot.render());
scriptRoot = merkle.verifyBranch(scriptRoot, path, pos);
mastRoot.writeBytes(scriptRoot);
mastRoot = hash256.digest(mastRoot.render());
if (!mastRoot.equals(program.data))
throw new ScriptError('WITNESS_PROGRAM_MISMATCH');
if (version === 0) {
stack.length -= 3 + subscripts;
for (let j = 0; j < stack.length; j++) {
if (stack.get(j).length > consensus.MAX_SCRIPT_PUSH)
throw new ScriptError('PUSH_SIZE');
}
scripts = scripts.render();
output = Script.fromRaw(scripts);
output.execute(stack, flags, tx, index, value, 1);
if (stack.length !== 0)
throw new ScriptError('EVAL_FALSE');
}
}
/**
* Inject properties from buffer reader.
* @private