More Error implementations
This commit is contained in:
parent
a69ae2c7ad
commit
67c0b8fba7
|
@ -1,7 +1,7 @@
|
|||
|
||||
[package]
|
||||
name = "bitcoin"
|
||||
version = "0.3.8"
|
||||
version = "0.3.9"
|
||||
authors = ["Andrew Poelstra <apoelstra@wpsoftware.net>"]
|
||||
license = "CC0-1.0"
|
||||
homepage = "https://github.com/apoelstra/rust-bitcoin/"
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
use std::hash;
|
||||
use std::char::from_digit;
|
||||
use std::default::Default;
|
||||
use std::{fmt, ops};
|
||||
use std::{error, fmt, ops};
|
||||
use serialize::hex::ToHex;
|
||||
|
||||
use crypto::digest::Digest;
|
||||
|
@ -101,8 +101,6 @@ impl hash::Hash for Script {
|
|||
/// would help you.
|
||||
#[derive(PartialEq, Eq, Debug, Clone)]
|
||||
pub enum Error {
|
||||
/// The script returns false no matter the input
|
||||
AnalyzeAlwaysReturnsFalse,
|
||||
/// Tried to set a boolean to both values, but neither worked
|
||||
AnalyzeNeitherBoolWorks,
|
||||
/// Tried to set a boolean to the given value, but it already
|
||||
|
@ -158,7 +156,59 @@ pub enum Error {
|
|||
/// An OP_VERIFY happened with zero on the stack
|
||||
VerifyFailed,
|
||||
}
|
||||
display_from_debug!(Error);
|
||||
|
||||
impl fmt::Display for Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
Error::Ecdsa(ref e) => fmt::Display::fmt(e, f),
|
||||
Error::EqualVerifyFailed(ref exp, ref got) => write!(f, "OP_EQUALVERIFY failed; {} != {}", exp, got),
|
||||
Error::MultisigBadKeyCount(n) => write!(f, "bad number {} of keys for multisignature", n),
|
||||
Error::MultisigBadSigCount(n) => write!(f, "bad number {} of signatures for multisignature", n),
|
||||
Error::NumEqualVerifyFailed(exp, got) => write!(f, "OP_NUMEQUALVERIFY failed; {} != {}", exp, got),
|
||||
_ => f.write_str(error::Error::description(self))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl error::Error for Error {
|
||||
fn cause(&self) -> Option<&error::Error> {
|
||||
match *self {
|
||||
Error::Ecdsa(ref e) => Some(e),
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
|
||||
fn description(&self) -> &'static str {
|
||||
match *self {
|
||||
Error::AnalyzeNeitherBoolWorks => "analyzer: switch on boolean but neither side is satisfiable",
|
||||
Error::AnalyzeSetBoolMismatch(_) => "analyzer: conflicting requirements on boolean",
|
||||
Error::AnalyzeValidateFailed => "analyzer: conflicting requirements on stack element",
|
||||
Error::BadPublicKey => "analyzer: CHECKSIG called with bad public key",
|
||||
Error::BadSignature => "analyzer: CHECKSIG called with bad signature",
|
||||
Error::Ecdsa(_) => "libsecp error",
|
||||
Error::ElseWithoutIf => "unexpected OP_ELSE",
|
||||
Error::EndifWithoutIf => "unexpected OP_ENDIF",
|
||||
Error::EqualVerifyFailed(_, _) => "OP_EQUALVERIFY failed",
|
||||
Error::IfEmptyStack => "OP_IF called with nothing on the stack",
|
||||
Error::IllegalOpcode => "an illegal opcode exists in the script",
|
||||
Error::InterpreterStackOverflow => "analyzer: stack overflow",
|
||||
Error::EarlyEndOfScript => "unexpected end of script",
|
||||
Error::ExecutedReturn => "OP_RETURN or equivalent was executed",
|
||||
Error::MultisigBadKeyCount(_) => "bad key count for multisignature",
|
||||
Error::MultisigBadSigCount(_) => "bad signature count for multisignature",
|
||||
Error::NegativePick => "OP_PICK called with negative index",
|
||||
Error::NegativeRoll => "OP_ROLL called with negative index",
|
||||
Error::NoTransaction => "OP_CHECKSIG evaluated outside of transaction environment",
|
||||
Error::NumEqualVerifyFailed(_, _) => "OP_NUMEQUALVERIFY failed",
|
||||
Error::NumericOverflow => "numeric overflow (number on stack larger than 4 bytes)",
|
||||
Error::PopEmptyStack => "stack was empty but script expected otherwise",
|
||||
Error::Unanalyzable => "analyzer: unable to determine script satisfiability",
|
||||
Error::Unsatisfiable => "analyzer: script is unsatisfiable",
|
||||
Error::VerifyEmptyStack => "OP_VERIFY called on an empty stack",
|
||||
Error::VerifyFailed => "OP_VERIFY called with false on top of stack"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A rule for validating an abstract stack element
|
||||
pub struct Validator {
|
||||
|
@ -2461,7 +2511,7 @@ impl Script {
|
|||
match stack.peek_mut().bool_value() {
|
||||
None => stack.peek_mut().set_bool_value(true).map(|_| stack.build_initial_stack()),
|
||||
Some(true) => Ok(stack.build_initial_stack()),
|
||||
Some(false) => Err(Error::AnalyzeAlwaysReturnsFalse)
|
||||
Some(false) => Err(Error::Unsatisfiable)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,8 @@ use blockdata::{opcodes, script};
|
|||
use crypto::{hmac, sha2};
|
||||
use crypto::mac::Mac;
|
||||
|
||||
use std::{error, fmt};
|
||||
|
||||
use network::constants::Network;
|
||||
use util::{address, hash};
|
||||
|
||||
|
@ -54,6 +56,45 @@ pub enum Error {
|
|||
TooManyKeys(usize)
|
||||
}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
Error::BadTweak(ref e) => fmt::Display::fmt(&e, f),
|
||||
Error::Secp(ref e) => fmt::Display::fmt(&e, f),
|
||||
Error::Script(ref e) => fmt::Display::fmt(&e, f),
|
||||
Error::UncompressedKey => f.write_str("encountered uncompressed secp public key"),
|
||||
Error::ExpectedKey => f.write_str("expected key when deserializing script"),
|
||||
Error::ExpectedChecksig => f.write_str("expected OP_*CHECKSIG* when deserializing script"),
|
||||
Error::TooFewKeys(n) => write!(f, "got {} keys, which was not enough", n),
|
||||
Error::TooManyKeys(n) => write!(f, "got {} keys, which was too many", n)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl error::Error for Error {
|
||||
fn cause(&self) -> Option<&error::Error> {
|
||||
match *self {
|
||||
Error::BadTweak(ref e) => Some(e),
|
||||
Error::Secp(ref e) => Some(e),
|
||||
Error::Script(ref e) => Some(e),
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
|
||||
fn description(&self) -> &'static str {
|
||||
match *self {
|
||||
Error::BadTweak(_) => "bad public key tweak",
|
||||
Error::Secp(_) => "libsecp256k1 error",
|
||||
Error::Script(_) => "script error",
|
||||
Error::UncompressedKey => "encountered uncompressed secp public key",
|
||||
Error::ExpectedKey => "expected key when deserializing script",
|
||||
Error::ExpectedChecksig => "expected OP_*CHECKSIG* when deserializing script",
|
||||
Error::TooFewKeys(_) => "too few keys for template",
|
||||
Error::TooManyKeys(_) => "too many keys for template"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An element of a script template
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
||||
enum TemplateElement {
|
||||
|
|
Loading…
Reference in New Issue