script: do not use return values for script.execute and Script.verify.

This commit is contained in:
Christopher Jeffrey 2017-08-10 09:41:01 -07:00
parent 6f96e64f70
commit 87e3ee1971
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
2 changed files with 43 additions and 57 deletions

View File

@ -480,7 +480,6 @@ Script.prototype.removeSeparators = function removeSeparators() {
* @param {Amount?} value - Previous output value.
* @param {Number?} version - Signature hash version (0=legacy, 1=segwit).
* @throws {ScriptError} Will be thrown on VERIFY failures, among other things.
* @returns {Boolean} Whether the execution was successful.
*/
Script.prototype.execute = function execute(stack, flags, tx, index, value, version) {
@ -1237,8 +1236,6 @@ Script.prototype.execute = function execute(stack, flags, tx, index, value, vers
if (state.length !== 0)
throw new ScriptError('UNBALANCED_CONDITIONAL');
return true;
};
/**
@ -2745,14 +2742,13 @@ Script.fromString = function fromString(code) {
* @param {Witness} witness
* @param {Script} output
* @param {TX} tx
* @param {Number} i
* @param {Number} index
* @param {Amount} value
* @param {VerifyFlags} flags
* @returns {Boolean}
* @throws {ScriptError}
*/
Script.verify = function verify(input, witness, output, tx, i, value, flags) {
Script.verify = function verify(input, witness, output, tx, index, value, flags) {
if (flags == null)
flags = Script.flags.STANDARD_VERIFY_FLAGS;
@ -2765,7 +2761,7 @@ Script.verify = function verify(input, witness, output, tx, i, value, flags) {
let stack = new Stack();
// Execute the input script
input.execute(stack, flags, tx, i, value, 0);
input.execute(stack, flags, tx, index, value, 0);
// Copy the stack for P2SH
let copy;
@ -2773,7 +2769,7 @@ Script.verify = function verify(input, witness, output, tx, i, value, flags) {
copy = stack.clone();
// Execute the previous output script.
output.execute(stack, flags, tx, i, value, 0);
output.execute(stack, flags, tx, index, value, 0);
// Verify the stack values.
if (stack.length === 0 || !Script.bool(stack.top(-1)))
@ -2789,7 +2785,7 @@ Script.verify = function verify(input, witness, output, tx, i, value, flags) {
throw new ScriptError('WITNESS_MALLEATED');
// Verify the program in the output script.
Script.verifyProgram(witness, output, flags, tx, i, value);
Script.verifyProgram(witness, output, flags, tx, index, value);
// Force a cleanstack
stack.length = 1;
@ -2810,10 +2806,10 @@ Script.verify = function verify(input, witness, output, tx, i, value, flags) {
// Grab the real redeem script
const raw = stack.pop();
const redeem = new Script(raw);
const redeem = Script.fromRaw(raw);
// Execute the redeem script.
redeem.execute(stack, flags, tx, i, value, 0);
redeem.execute(stack, flags, tx, index, value, 0);
// Verify the the stack values.
if (stack.length === 0 || !Script.bool(stack.top(-1)))
@ -2827,7 +2823,7 @@ Script.verify = function verify(input, witness, output, tx, i, value, flags) {
throw new ScriptError('WITNESS_MALLEATED_P2SH');
// Verify the program in the redeem script.
Script.verifyProgram(witness, redeem, flags, tx, i, value);
Script.verifyProgram(witness, redeem, flags, tx, index, value);
// Force a cleanstack.
stack.length = 1;
@ -2847,8 +2843,6 @@ Script.verify = function verify(input, witness, output, tx, i, value, flags) {
if (!hadWitness && witness.items.length > 0)
throw new ScriptError('WITNESS_UNEXPECTED');
}
return true;
};
/**
@ -2859,13 +2853,12 @@ Script.verify = function verify(input, witness, output, tx, i, value, flags) {
* @param {Script} output
* @param {VerifyFlags} flags
* @param {TX} tx
* @param {Number} i
* @param {Number} index
* @param {Amount} value
* @returns {Boolean}
* @throws {ScriptError}
*/
Script.verifyProgram = function verifyProgram(witness, output, flags, tx, i, value) {
Script.verifyProgram = function verifyProgram(witness, output, flags, tx, index, value) {
const program = output.toProgram();
assert(program, 'verifyProgram called on non-witness-program.');
@ -2895,7 +2888,7 @@ Script.verifyProgram = function verifyProgram(witness, output, flags, tx, i, val
throw new ScriptError('WITNESS_PROGRAM_WRONG_LENGTH');
}
} else if ((flags & Script.flags.VERIFY_MAST) && program.version === 1) {
return Script.verifyMast(program, stack, output, flags, tx, i);
return Script.verifyMast(program, stack, output, flags, tx, index);
} else {
// Anyone can spend (we can return true here
// if we want to always relay these transactions).
@ -2916,13 +2909,11 @@ Script.verifyProgram = function verifyProgram(witness, output, flags, tx, i, val
}
// Verify the redeem script.
redeem.execute(stack, flags, tx, i, value, 1);
redeem.execute(stack, flags, tx, index, value, 1);
// Verify the stack values.
if (stack.length !== 1 || !Script.bool(stack.top(-1)))
throw new ScriptError('EVAL_FALSE');
return true;
};
/**
@ -2932,13 +2923,12 @@ Script.verifyProgram = function verifyProgram(witness, output, flags, tx, i, val
* @param {Script} output
* @param {VerifyFlags} flags
* @param {TX} tx
* @param {Number} i
* @param {Number} index
* @param {Amount} value
* @returns {Boolean}
* @throws {ScriptError}
*/
Script.verifyMast = function verifyMast(program, stack, output, flags, tx, i, value) {
Script.verifyMast = function verifyMast(program, stack, output, flags, tx, index, value) {
assert(program.version === 1);
assert((flags & Script.flags.VERIFY_MAST) !== 0);
@ -2963,7 +2953,7 @@ Script.verifyMast = function verifyMast(program, stack, output, flags, tx, i, va
let version = 0;
for (let j = 1; j < metadata.length; j++)
version |= metadata[i] << 8 * (j - 1);
version |= metadata[j] << 8 * (j - 1);
if (version < 0)
version += 0x100000000;
@ -3008,7 +2998,7 @@ Script.verifyMast = function verifyMast(program, stack, output, flags, tx, i, va
throw new ScriptError('INVALID_MAST_STACK');
for (let j = 0; j < posdata.length; j++)
pos |= posdata[i] << 8 * j;
pos |= posdata[j] << 8 * j;
if (pos < 0)
pos += 0x100000000;
@ -3051,13 +3041,11 @@ Script.verifyMast = function verifyMast(program, stack, output, flags, tx, i, va
scripts = scripts.render();
output = new Script(scripts);
output.execute(stack, flags, tx, i, value, 1);
output.execute(stack, flags, tx, index, value, 1);
if (stack.length !== 0)
throw new ScriptError('EVAL_FALSE');
}
return true;
};
/**

View File

@ -14,10 +14,7 @@ const opcodes = Script.opcodes;
const scripts = require('./data/script-tests.json');
function isSuccess(res, stack) {
if (!res)
return false;
function isSuccess(stack) {
if (stack.length === 0)
return false;
@ -126,9 +123,7 @@ describe('Script', function() {
const stack = new Stack();
input.execute(stack);
const res = output.execute(stack);
assert(res);
output.execute(stack);
assert.deepEqual(stack.items, [[1], [3], [5]]);
}
@ -147,10 +142,10 @@ describe('Script', function() {
]);
const stack = new Stack();
input.execute(stack);
const res = output.execute(stack);
assert(res);
input.execute(stack);
output.execute(stack);
assert.deepEqual(stack.items, [[1], [4], [5]]);
}
@ -168,9 +163,8 @@ describe('Script', function() {
const stack = new Stack();
input.execute(stack);
output.execute(stack);
const res = output.execute(stack);
assert(res);
assert.deepEqual(stack.items, [[1], [3], [5]]);
}
@ -186,10 +180,10 @@ describe('Script', function() {
]);
const stack = new Stack();
input.execute(stack);
const res = output.execute(stack);
assert(res);
input.execute(stack);
output.execute(stack);
assert.deepEqual(stack.items, [[1], [5]]);
}
@ -205,10 +199,10 @@ describe('Script', function() {
]);
const stack = new Stack();
input.execute(stack);
const res = output.execute(stack);
assert(res);
input.execute(stack);
output.execute(stack);
assert.deepEqual(stack.items, [[1], [3], [5]]);
}
});
@ -228,8 +222,10 @@ describe('Script', function() {
const stack = new Stack();
assert(input.execute(stack));
assert(isSuccess(output.execute(stack), stack));
input.execute(stack);
output.execute(stack);
assert(isSuccess(stack));
});
it('should handle CScriptNums correctly', () => {
@ -247,8 +243,10 @@ describe('Script', function() {
const stack = new Stack();
assert(input.execute(stack));
assert(isSuccess(output.execute(stack), stack));
input.execute(stack);
output.execute(stack);
assert(isSuccess(stack));
});
it('should handle OP_ROLL correctly', () => {
@ -270,8 +268,10 @@ describe('Script', function() {
const stack = new Stack();
assert(input.execute(stack));
assert(isSuccess(output.execute(stack), stack));
input.execute(stack);
output.execute(stack);
assert(isSuccess(stack));
});
for (const data of scripts) {
@ -330,22 +330,20 @@ describe('Script', function() {
tx.refresh();
}
let err, res;
let err;
try {
res = Script.verify(input, witness, output, tx, 0, value, flags);
Script.verify(input, witness, output, tx, 0, value, flags);
} catch (e) {
err = e;
}
if (expected !== 'OK') {
assert(!res);
assert(err);
assert.strictEqual(err.code, expected);
return;
}
assert.ifError(err);
assert(res);
});
}
}