Add much more agressive provably-false checker

Now unspendable outs are determined by attempting to create a minimal
satisfying input script. If this can't be done, the output is unspendable.
(Unfortunately this "minimal satisfying script" is not (yet) something
that can be shown to the user, since it is more a bundle of constraints
than actual data pushes.)

Current limitations:
  - OP_ADD and friends mean the checker gives the script a free pass.
    There is no fundamental reason for this, I just didn't get to it
    yet.

  - Pubkeys are checked for DER encoding but signatures aren't. This
    is because secp256k1 exposes a method for pubkeys, but not one
    for sigs :). Signatures are loosely length checked.
This commit is contained in:
Andrew Poelstra 2014-08-31 09:50:46 -07:00
parent 8f5c28a533
commit 340b569c73
5 changed files with 1421 additions and 265 deletions

File diff suppressed because one or more lines are too long

View File

@ -156,7 +156,11 @@ macro_rules! impl_array_newtype(
$thing::from_slice(self.as_slice()) $thing::from_slice(self.as_slice())
} }
} }
}
)
macro_rules! impl_array_newtype_show(
($thing:ident) => {
impl ::std::fmt::Show for $thing { impl ::std::fmt::Show for $thing {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
write!(f, concat!(stringify!($thing), "({})"), self.as_slice()) write!(f, concat!(stringify!($thing), "({})"), self.as_slice())

View File

@ -33,6 +33,9 @@
#![feature(overloaded_calls)] #![feature(overloaded_calls)]
#![feature(unsafe_destructor)] #![feature(unsafe_destructor)]
#![feature(default_type_params)] #![feature(default_type_params)]
#![feature(struct_variant)]
#![feature(unboxed_closure_sugar)]
#![feature(unboxed_closures)]
#![comment = "Rust Bitcoin Library"] #![comment = "Rust Bitcoin Library"]
#![license = "CC0"] #![license = "CC0"]

View File

@ -36,6 +36,12 @@ use util::uint::Uint256;
pub struct Sha256dHash([u8, ..32]); pub struct Sha256dHash([u8, ..32]);
impl_array_newtype!(Sha256dHash, u8, 32) impl_array_newtype!(Sha256dHash, u8, 32)
impl ::std::fmt::Show for Sha256dHash {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
write!(f, "{}", self.be_hex_string().as_slice())
}
}
/// A RIPEMD-160 hash /// A RIPEMD-160 hash
pub struct Ripemd160Hash([u8, ..20]); pub struct Ripemd160Hash([u8, ..20]);

View File

@ -36,10 +36,12 @@ use util::base58::{Base58Error,
/// A chain code /// A chain code
pub struct ChainCode([u8, ..32]); pub struct ChainCode([u8, ..32]);
impl_array_newtype!(ChainCode, u8, 32) impl_array_newtype!(ChainCode, u8, 32)
impl_array_newtype_show!(ChainCode)
/// A fingerprint /// A fingerprint
pub struct Fingerprint([u8, ..4]); pub struct Fingerprint([u8, ..4]);
impl_array_newtype!(Fingerprint, u8, 4) impl_array_newtype!(Fingerprint, u8, 4)
impl_array_newtype_show!(Fingerprint)
impl Default for Fingerprint { impl Default for Fingerprint {
fn default() -> Fingerprint { Fingerprint([0, 0, 0, 0]) } fn default() -> Fingerprint { Fingerprint([0, 0, 0, 0]) }