Commit 99e4e0b5 authored by Daniel Connolly's avatar Daniel Connolly

add ScriptException sub-classes for specific errors

parent 091d7bda
/*
* Copyright 2011 Google Inc.
* Copyright 2018 the bitcoinj-cash developers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
......@@ -16,7 +17,7 @@
package org.bitcoinj.core;
@SuppressWarnings("serial")
public class ScriptException extends VerificationException {
public ScriptException(String msg) {
......@@ -26,4 +27,111 @@ public class ScriptException extends VerificationException {
public ScriptException(String msg, Exception e) {
super(msg, e);
}
public static class BadOpcodeException extends ScriptException {
public BadOpcodeException() { super("an illegal opcode is present in the script"); }
}
public static class DisabledOpcodeException extends ScriptException {
public DisabledOpcodeException() { super("script includes a disabled opcode"); }
}
public static class DiscourageUpgradableNopsException extends ScriptException {
public DiscourageUpgradableNopsException() { super("script used a reserved opcode"); }
}
public static class DivByZeroException extends ScriptException {
public DivByZeroException() { super("divide by zero error"); }
}
public static class EqualVerifyException extends ScriptException {
public EqualVerifyException() { super("OP_EQUALVERIFY failed, non-equal operands"); }
}
public static class EvalFalseException extends ScriptException {
public EvalFalseException() { super("script evaluated false"); }
}
public static class InvalidAltStackOperationException extends ScriptException {
public InvalidAltStackOperationException() { super("the operation was invalid given the contents of the altstack"); }
}
public static class InvalidNumberRangeException extends ScriptException {
public InvalidNumberRangeException() { super("operand is not a number in the valid range"); }
}
public static class InvalidStackOperationException extends ScriptException {
/* some possible causes:
* - not enough values on the stack for the operation
*/
public InvalidStackOperationException() { super("the operation was invalid given the contents of the stack"); }
}
public static class ModByZeroException extends ScriptException {
public ModByZeroException() { super("modulo by zero error"); }
}
public static class NonStandardScriptException extends ScriptException {
public NonStandardScriptException() { super("script is not a recognized standard script"); }
}
public static class NullDummyException extends ScriptException {
public NullDummyException() { super("CHECKMULTISIG with non-null nulldummy"); }
}
public static class NumEqualVerifyException extends ScriptException {
public NumEqualVerifyException() { super("OP_NUMEQUALVERIFY failed, non-equal operands"); }
}
public static class OpCountException extends ScriptException {
public OpCountException() { super("script contains too many opcodes"); }
}
public static class OperandSizeException extends ScriptException {
public OperandSizeException() { super("invalid operand size"); }
}
public static class OpReturnException extends ScriptException {
public OpReturnException() { super("the script called OP_RETURN"); }
}
public static class PubKeyCountException extends ScriptException {
public PubKeyCountException() { super("there are too many, or not enough, public keys"); }
}
public static class PushSizeException extends ScriptException {
/* some possible causes:
* - result of OP_CAT would be too large
* - result of NUM2BIN would be too large
*/
public PushSizeException() { super("attempted to push value on the stack that was too large"); }
}
public static class ScriptSizeException extends ScriptException {
public ScriptSizeException() { super("the script is too large"); }
}
public static class SigCountException extends ScriptException {
public SigCountException() { super("sig count out of range"); }
}
public static class SigPushOnlyException extends ScriptException {
public SigPushOnlyException() { super("attempted to spend a P2SH scriptPubKey with a script that contained script ops"); }
}
public static class SplitRangeException extends ScriptException {
public SplitRangeException() { super("invalid OP_SPLIT range"); }
}
public static class StackSizeException extends ScriptException {
public StackSizeException() { super("stack is, or would be, too large"); }
}
public static class UnbalancedConditionalException extends ScriptException {
public UnbalancedConditionalException() { super("the script contains an unbalanced conditional"); }
}
public static class VerifyException extends ScriptException {
public VerifyException() { super("the VERIFY failed"); }
}
}
......@@ -718,7 +718,7 @@ public class ScriptTest {
Assert.assertArrayEquals(bitwiseScript(first, secondOverflow, "CAT"), cat);
fail("CAT should fail when result is more than " + MAX_SCRIPT_ELEMENT_SIZE);
} catch (ScriptException e) {
Assert.assertEquals("Push value size limit exceeded.", e.getMessage());
Assert.assertEquals("attempted to push value on the stack that was too large", e.getMessage());
}
}
......@@ -740,8 +740,8 @@ public class ScriptTest {
Assert.assertArrayEquals(B, executeMonolithScript(new ScriptBuilder().data(A_B).number(1).op(ScriptOpCodes.OP_SPLIT).build()));
Assert.assertArrayEquals(EMPTY, executeMonolithScript(new ScriptBuilder().data(A_B).number(2).op(ScriptOpCodes.OP_SPLIT).build()));
executeFailedMonolithScript(new ScriptBuilder().op(ScriptOpCodes.OP_SPLIT).build(), "Invalid stack operation.");
executeFailedMonolithScript(new ScriptBuilder().data(EMPTY).number(1).op(ScriptOpCodes.OP_SPLIT).build(), "Invalid OP_SPLIT range.");
executeFailedMonolithScript(new ScriptBuilder().op(ScriptOpCodes.OP_SPLIT).build(), "the operation was invalid given the contents of the stack");
executeFailedMonolithScript(new ScriptBuilder().data(EMPTY).number(1).op(ScriptOpCodes.OP_SPLIT).build(), "invalid OP_SPLIT range");
}
/** BIN2NUM **/
......@@ -757,20 +757,20 @@ public class ScriptTest {
checkBin2NumOp(toByteArray(0xab, 0xcd, 0x7f, 0x42), toByteArray(0xab, 0xcd, 0x7f, 0x42, 0x00));
// Empty stack
executeFailedMonolithScript(new ScriptBuilder().op(ScriptOpCodes.OP_BIN2NUM).build(), "Invalid stack operation.");
executeFailedMonolithScript(new ScriptBuilder().op(ScriptOpCodes.OP_NUM2BIN).build(), "Invalid stack operation.");
executeFailedMonolithScript(new ScriptBuilder().op(ScriptOpCodes.OP_BIN2NUM).build(), "the operation was invalid given the contents of the stack");
executeFailedMonolithScript(new ScriptBuilder().op(ScriptOpCodes.OP_NUM2BIN).build(), "the operation was invalid given the contents of the stack");
// Values that do not fit in 4 bytes are considered out of range for BIN2NUM
executeFailedMonolithScript(new ScriptBuilder().data(toByteArray(0xab, 0xcd, 0xef, 0xc2, 0x80)).op(ScriptOpCodes.OP_BIN2NUM).build(), "Given operand is not a number within the valid range [-2^31...2^31]");
executeFailedMonolithScript(new ScriptBuilder().data(toByteArray(0x00, 0x00, 0x00, 0x80, 0x80)).op(ScriptOpCodes.OP_BIN2NUM).build(), "Given operand is not a number within the valid range [-2^31...2^31]");
executeFailedMonolithScript(new ScriptBuilder().data(toByteArray(0xab, 0xcd, 0xef, 0xc2, 0x80)).op(ScriptOpCodes.OP_BIN2NUM).build(), "operand is not a number in the valid range");
executeFailedMonolithScript(new ScriptBuilder().data(toByteArray(0x00, 0x00, 0x00, 0x80, 0x80)).op(ScriptOpCodes.OP_BIN2NUM).build(), "operand is not a number in the valid range");
// NUM2BIN require 2 elements on the stack.
executeFailedMonolithScript(new ScriptBuilder().data(toByteArray( 0x00)).op(ScriptOpCodes.OP_NUM2BIN).build(), "Invalid stack operation.");
executeFailedMonolithScript(new ScriptBuilder().data(toByteArray( 0x00)).op(ScriptOpCodes.OP_NUM2BIN).build(), "the operation was invalid given the contents of the stack");
executeFailedMonolithScript(new ScriptBuilder().data(new byte[0]).data(toByteArray(0x09, 0x02)).op(ScriptOpCodes.OP_NUM2BIN).build(), "Push value size limit exceeded.");
executeFailedMonolithScript(new ScriptBuilder().data(new byte[0]).data(toByteArray(0x09, 0x02)).op(ScriptOpCodes.OP_NUM2BIN).build(), "attempted to push value on the stack that was too large");
// Check that the requested encoding is possible.
executeFailedMonolithScript(new ScriptBuilder().data(toByteArray(0xab, 0xcd, 0xef, 0x80)).data(toByteArray(0x03)).op(ScriptOpCodes.OP_NUM2BIN).build(), "The requested encoding is impossible to satisfy.");
executeFailedMonolithScript(new ScriptBuilder().data(toByteArray(0xab, 0xcd, 0xef, 0x80)).data(toByteArray(0x03)).op(ScriptOpCodes.OP_NUM2BIN).build(), "attempted to push value on the stack that was too large");
}
private void checkBin2NumOp(byte[] n, byte[] expected) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment