Make contracthashtool check that the number of keys matches the template's requirement

This is easy to satisfy given that the template-to-script code takes a
slice of keys. Just do &keys[..n_keys] if you have too many keys. (If
you have too few you're SOL no matter what.) This way we can catch
likely configuration errors without putting much of a burden on users
who legitimately have more keys than the template requires.

Also add a method required_keys() to Template so that users can check
how many keys they ought to have.
This commit is contained in:
Andrew Poelstra 2015-10-25 08:37:32 -05:00
parent 125dde4cb0
commit 3491c5057e
2 changed files with 30 additions and 3 deletions

View File

@ -1,7 +1,7 @@
[package] [package]
name = "bitcoin" name = "bitcoin"
version = "0.3.6" version = "0.3.7"
authors = ["Andrew Poelstra <apoelstra@wpsoftware.net>"] authors = ["Andrew Poelstra <apoelstra@wpsoftware.net>"]
license = "CC0-1.0" license = "CC0-1.0"
homepage = "https://github.com/apoelstra/rust-bitcoin/" homepage = "https://github.com/apoelstra/rust-bitcoin/"

View File

@ -49,7 +49,9 @@ pub enum Error {
/// we got something else. /// we got something else.
ExpectedChecksig, ExpectedChecksig,
/// Did not have enough keys to instantiate a script template /// Did not have enough keys to instantiate a script template
TooFewKeys(usize) TooFewKeys(usize),
/// Had too many keys; template does not match key list
TooManyKeys(usize)
} }
/// An element of a script template /// An element of a script template
@ -81,7 +83,16 @@ impl Template {
} }
} }
} }
if key_index == keys.len() {
Ok(ret.into_script()) Ok(ret.into_script())
} else {
Err(Error::TooManyKeys(keys.len()))
}
}
/// Returns the number of keys this template requires to instantiate
pub fn required_keys(&self) -> usize {
self.0.iter().filter(|e| **e == TemplateElement::Key).count()
} }
} }
@ -284,6 +295,22 @@ mod tests {
assert_eq!(tweaked_pks[1], tweaked_pk2); assert_eq!(tweaked_pks[1], tweaked_pk2);
assert_eq!(tweaked_pks[2], tweaked_pk3); assert_eq!(tweaked_pks[2], tweaked_pk3);
} }
#[test]
fn bad_key_number() {
let secp = Secp256k1::new();
let alpha_keys = alpha_keys!(&secp);
let template_short = Template::from(&hex!("55fefefefefefe57AE")[..]);
let template_long = Template::from(&hex!("55fefefefefefefefe57AE")[..]);
let template = Template::from(&hex!("55fefefefefefefe57AE")[..]);
assert_eq!(template_short.required_keys(), 6);
assert_eq!(template_long.required_keys(), 8);
assert_eq!(template.required_keys(), 7);
assert_eq!(template_short.to_script(alpha_keys), Err(Error::TooManyKeys(7)));
assert_eq!(template_long.to_script(alpha_keys), Err(Error::TooFewKeys(7)));
assert!(template.to_script(alpha_keys).is_ok());
}
} }