diff --git a/src/descriptor/key.rs b/src/descriptor/key.rs index 5ba61c458..28eb545ca 100644 --- a/src/descriptor/key.rs +++ b/src/descriptor/key.rs @@ -180,7 +180,7 @@ impl DescriptorXKey { Some((fingerprint, path)) => Some(( *fingerprint, path.into_iter() - .chain(hardened_path.into_iter()) + .chain(hardened_path.iter()) .cloned() .collect(), )), @@ -456,7 +456,7 @@ impl DescriptorPublicKey { DescriptorPublicKey::XPub(DescriptorXKey { origin: xpub.origin, xkey: xpub.xkey, - derivation_path: derivation_path, + derivation_path, wildcard: Wildcard::None, }) } diff --git a/src/expression.rs b/src/expression.rs index 17bff33cf..9bbfa1888 100644 --- a/src/expression.rs +++ b/src/expression.rs @@ -173,6 +173,7 @@ impl<'a> Tree<'a> { } /// Parses a tree from a string + #[allow(clippy::should_implement_trait)] // Cannot use std::str::FromStr because of lifetimes. pub fn from_str(s: &'a str) -> Result, Error> { // Filter out non-ASCII because we byte-index strings all over the // place and Rust gets very upset when you splinch a string. diff --git a/src/interpreter/stack.rs b/src/interpreter/stack.rs index 41d601bc3..b8288260f 100644 --- a/src/interpreter/stack.rs +++ b/src/interpreter/stack.rs @@ -228,9 +228,9 @@ impl<'txin> Stack<'txin> { /// The reason we don't need to copy the Script semantics is that /// Miniscript never evaluates integers and it is safe to treat them as /// booleans - pub(super) fn evaluate_after<'intp>( + pub(super) fn evaluate_after( &mut self, - n: &'intp u32, + n: &u32, age: u32, ) -> Option> { if age >= *n { @@ -247,9 +247,9 @@ impl<'txin> Stack<'txin> { /// The reason we don't need to copy the Script semantics is that /// Miniscript never evaluates integers and it is safe to treat them as /// booleans - pub(super) fn evaluate_older<'intp>( + pub(super) fn evaluate_older( &mut self, - n: &'intp u32, + n: &u32, height: u32, ) -> Option> { if height >= *n { @@ -262,9 +262,9 @@ impl<'txin> Stack<'txin> { /// Helper function to evaluate a Sha256 Node. /// `SIZE 32 EQUALVERIFY SHA256 h EQUAL` - pub(super) fn evaluate_sha256<'intp>( + pub(super) fn evaluate_sha256( &mut self, - hash: &'intp sha256::Hash, + hash: &sha256::Hash, ) -> Option> { if let Some(Element::Push(preimage)) = self.pop() { if preimage.len() != 32 { @@ -287,9 +287,9 @@ impl<'txin> Stack<'txin> { /// Helper function to evaluate a Hash256 Node. /// `SIZE 32 EQUALVERIFY HASH256 h EQUAL` - pub(super) fn evaluate_hash256<'intp>( + pub(super) fn evaluate_hash256( &mut self, - hash: &'intp sha256d::Hash, + hash: &sha256d::Hash, ) -> Option> { if let Some(Element::Push(preimage)) = self.pop() { if preimage.len() != 32 { @@ -312,9 +312,9 @@ impl<'txin> Stack<'txin> { /// Helper function to evaluate a Hash160 Node. /// `SIZE 32 EQUALVERIFY HASH160 h EQUAL` - pub(super) fn evaluate_hash160<'intp>( + pub(super) fn evaluate_hash160( &mut self, - hash: &'intp hash160::Hash, + hash: &hash160::Hash, ) -> Option> { if let Some(Element::Push(preimage)) = self.pop() { if preimage.len() != 32 { @@ -337,9 +337,9 @@ impl<'txin> Stack<'txin> { /// Helper function to evaluate a RipeMd160 Node. /// `SIZE 32 EQUALVERIFY RIPEMD160 h EQUAL` - pub(super) fn evaluate_ripemd160<'intp>( + pub(super) fn evaluate_ripemd160( &mut self, - hash: &'intp ripemd160::Hash, + hash: &ripemd160::Hash, ) -> Option> { if let Some(Element::Push(preimage)) = self.pop() { if preimage.len() != 32 { diff --git a/src/lib.rs b/src/lib.rs index 68050a3cf..70b379065 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -54,36 +54,31 @@ //! //! ```rust //! use std::str::FromStr; -//! use miniscript::{DescriptorTrait}; +//! use miniscript::DescriptorTrait; //! -//! fn main() { -//! let desc = miniscript::Descriptor::< -//! bitcoin::PublicKey, -//! >::from_str("\ -//! sh(wsh(or_d(\ -//! c:pk_k(020e0338c96a8870479f2396c373cc7696ba124e8635d41b0ea581112b67817261),\ -//! c:pk_k(0250863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b2352)\ -//! )))\ +//! let desc = miniscript::Descriptor::::from_str("\ +//! sh(wsh(or_d(\ +//! c:pk_k(020e0338c96a8870479f2396c373cc7696ba124e8635d41b0ea581112b67817261),\ +//! c:pk_k(0250863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b2352)\ +//! )))\ //! ").unwrap(); //! -//! // Derive the P2SH address -//! assert_eq!( -//! desc.address(bitcoin::Network::Bitcoin).unwrap().to_string(), -//! "3CJxbQBfWAe1ZkKiGQNEYrioV73ZwvBWns" -//! ); +//! // Derive the P2SH address +//! assert_eq!( +//! desc.address(bitcoin::Network::Bitcoin).unwrap().to_string(), +//! "3CJxbQBfWAe1ZkKiGQNEYrioV73ZwvBWns" +//! ); //! -//! // Check whether the descriptor is safe -//! // This checks whether all spend paths are accessible in bitcoin network. -//! // It maybe possible that some of the spend require more than 100 elements in Wsh scripts -//! // Or they contain a combination of timelock and heightlock. -//! assert!(desc.sanity_check().is_ok()); +//! // Check whether the descriptor is safe. This checks whether all spend paths are accessible in +//! // the Bitcoin network. It may be possible that some of the spend paths require more than 100 +//! // elements in Wsh scripts or they contain a combination of timelock and heightlock. +//! assert!(desc.sanity_check().is_ok()); //! -//! // Estimate the satisfaction cost -//! assert_eq!(desc.max_satisfaction_weight().unwrap(), 293); -//! } +//! // Estimate the satisfaction cost +//! assert_eq!(desc.max_satisfaction_weight().unwrap(), 293); //! ``` //! -//! + #![cfg_attr(all(test, feature = "unstable"), feature(test))] // Coding conventions #![deny(unsafe_code)] diff --git a/src/miniscript/astelem.rs b/src/miniscript/astelem.rs index 3ef00ca00..09d643220 100644 --- a/src/miniscript/astelem.rs +++ b/src/miniscript/astelem.rs @@ -194,7 +194,7 @@ impl Terminal { Arc::new(right.real_translate_pk(fpk, fpkh)?), ), Terminal::OrI(ref left, ref right) => Terminal::OrI( - Arc::new(left.real_translate_pk(&mut *&mut *fpk, &mut *&mut *fpkh)?), + Arc::new(left.real_translate_pk(&mut *fpk, &mut *fpkh)?), Arc::new(right.real_translate_pk(fpk, fpkh)?), ), Terminal::Thresh(k, ref subs) => { diff --git a/src/miniscript/mod.rs b/src/miniscript/mod.rs index ad38ca138..6410cc1dd 100644 --- a/src/miniscript/mod.rs +++ b/src/miniscript/mod.rs @@ -166,37 +166,37 @@ impl Miniscript { } /// Attempt to parse a Script into Miniscript representation. - /// This function will fail parsing for scripts that do not clear - /// the [Miniscript::sanity_check] checks. Use [Miniscript::parse_insane] to + /// + /// This function will fail parsing for scripts that do not clear the + /// [`Miniscript::sanity_check`] checks. Use [`Miniscript::parse_insane`] to /// parse such scripts. /// /// ## Decode/Parse a miniscript from script hex /// /// ```rust - /// use miniscript::Miniscript; - /// use miniscript::{Segwitv0, Tap}; + /// use miniscript::{Miniscript, Segwitv0, Tap}; /// use miniscript::bitcoin::secp256k1::XOnlyPublicKey; + /// use miniscript::bitcoin::hashes::hex::FromHex; + /// /// type Segwitv0Script = Miniscript; /// type TapScript = Miniscript; - /// use bitcoin::hashes::hex::FromHex; - /// fn main() { - /// // parse x-only miniscript in Taproot context - /// let tapscript_ms = TapScript::parse(&bitcoin::Script::from(Vec::::from_hex( - /// "202788ee41e76f4f3af603da5bc8fa22997bc0344bb0f95666ba6aaff0242baa99ac", - /// ).expect("Even length hex"))) + /// + /// // parse x-only miniscript in Taproot context + /// let tapscript_ms = TapScript::parse(&bitcoin::Script::from(Vec::::from_hex( + /// "202788ee41e76f4f3af603da5bc8fa22997bc0344bb0f95666ba6aaff0242baa99ac", + /// ).expect("Even length hex"))) /// .expect("Xonly keys are valid only in taproot context"); - /// // tapscript fails decoding when we use them with compressed keys - /// let err = TapScript::parse(&bitcoin::Script::from(Vec::::from_hex( - /// "21022788ee41e76f4f3af603da5bc8fa22997bc0344bb0f95666ba6aaff0242baa99ac", - /// ).expect("Even length hex"))) + /// // tapscript fails decoding when we use them with compressed keys + /// let err = TapScript::parse(&bitcoin::Script::from(Vec::::from_hex( + /// "21022788ee41e76f4f3af603da5bc8fa22997bc0344bb0f95666ba6aaff0242baa99ac", + /// ).expect("Even length hex"))) /// .expect_err("Compressed keys cannot be used in Taproot context"); - /// // Segwitv0 succeeds decoding with full keys. - /// Segwitv0Script::parse(&bitcoin::Script::from(Vec::::from_hex( - /// "21022788ee41e76f4f3af603da5bc8fa22997bc0344bb0f95666ba6aaff0242baa99ac", - /// ).expect("Even length hex"))) + /// // Segwitv0 succeeds decoding with full keys. + /// Segwitv0Script::parse(&bitcoin::Script::from(Vec::::from_hex( + /// "21022788ee41e76f4f3af603da5bc8fa22997bc0344bb0f95666ba6aaff0242baa99ac", + /// ).expect("Even length hex"))) /// .expect("Compressed keys are allowed in Segwit context"); /// - /// } /// ``` pub fn parse(script: &script::Script) -> Result, Error> { let ms = Self::parse_insane(script)?; diff --git a/src/miniscript/types/extra_props.rs b/src/miniscript/types/extra_props.rs index b8cfe0d5c..7046287be 100644 --- a/src/miniscript/types/extra_props.rs +++ b/src/miniscript/types/extra_props.rs @@ -761,9 +761,9 @@ impl Property for ExtData { S: FnMut(usize) -> Result, { let mut pk_cost = 1 + script_num_size(k); //Equal and k - let mut ops_count = 0 as usize; + let mut ops_count = 0; let mut ops_count_sat_vec = Vec::with_capacity(n); - let mut ops_count_nsat_sum = 0 as usize; + let mut ops_count_nsat_sum = 0; let mut op_count_sat = Some(0); let mut timelocks = Vec::with_capacity(n); let mut stack_elem_count_sat_vec = Vec::with_capacity(n); diff --git a/src/policy/compiler.rs b/src/policy/compiler.rs index 5cd0eeda2..c256bae31 100644 --- a/src/policy/compiler.rs +++ b/src/policy/compiler.rs @@ -129,7 +129,7 @@ impl CompilationKey { CompilationKey { ty, expensive_verify, - dissat_prob: dissat_prob.and_then(|x| Some(OrdF64(x))), + dissat_prob: dissat_prob.map(OrdF64), } } } @@ -353,6 +353,7 @@ impl Property for CompilerExtData { }) } + #[allow(clippy::manual_map)] // Complex if/let is better as is. fn or_i(l: Self, r: Self) -> Result { let lprob = l .branch_prob @@ -394,11 +395,7 @@ impl Property for CompilerExtData { Ok(CompilerExtData { branch_prob: None, sat_cost: aprob * (a.sat_cost + b.sat_cost) + cprob * (adis + c.sat_cost), - dissat_cost: if let Some(cdis) = c.dissat_cost { - Some(adis + cdis) - } else { - None - }, + dissat_cost: c.dissat_cost.map(|cdis| adis + cdis), }) } @@ -508,8 +505,8 @@ impl AstElemExt { let comp_ext_data = CompilerExtData::type_check(&ast, lookup_ext)?; Ok(AstElemExt { ms: Arc::new(Miniscript { - ty: ty, - ext: ext, + ty, + ext, node: ast, phantom: PhantomData, }), @@ -647,7 +644,7 @@ fn insert_elem( return false; } - if let Err(_) = Ctx::check_local_validity(&elem.ms) { + if Ctx::check_local_validity(&elem.ms).is_err() { return false; } @@ -664,11 +661,11 @@ fn insert_elem( let existing_elem_cost = existing_elem.cost_1d(sat_prob, dissat_prob); existing_key.is_subtype(elem_key) && existing_elem_cost <= elem_cost }) - .fold(false, |acc, x| acc || x); + .any(|x| x); if !is_worse { // If the element is not worse any element in the map, remove elements // whose subtype is the current element and have worse cost. - *map = mem::replace(map, BTreeMap::new()) + *map = mem::take(map) .into_iter() .filter(|&(ref existing_key, ref existing_elem)| { let existing_elem_cost = existing_elem.cost_1d(sat_prob, dissat_prob); @@ -703,8 +700,8 @@ fn insert_elem_closure( while !cast_stack.is_empty() { let current = cast_stack.pop_front().unwrap(); - for i in 0..casts.len() { - if let Ok(new_ext) = casts[i].cast(¤t) { + for c in &casts { + if let Ok(new_ext) = c.cast(¤t) { if insert_elem(map, new_ext.clone(), sat_prob, dissat_prob) { cast_stack.push_back(new_ext); } @@ -735,9 +732,9 @@ fn insert_best_wrapped( if dissat_prob.is_some() { let casts: [Cast; 10] = all_casts::(); - for i in 0..casts.len() { + for c in &casts { for x in best_compilations(policy_cache, policy, sat_prob, None)?.values() { - if let Ok(new_ext) = casts[i].cast(x) { + if let Ok(new_ext) = c.cast(x) { insert_elem_closure(map, new_ext, sat_prob, dissat_prob); } } @@ -760,7 +757,7 @@ where { //Check the cache for hits let ord_sat_prob = OrdF64(sat_prob); - let ord_dissat_prob = dissat_prob.and_then(|x| Some(OrdF64(x))); + let ord_dissat_prob = dissat_prob.map(OrdF64); if let Some(ret) = policy_cache.get(&(policy.clone(), ord_sat_prob, ord_dissat_prob)) { return Ok(ret.clone()); } @@ -812,9 +809,7 @@ where insert_wrap!(AstElemExt::terminal(Terminal::True)); } Concrete::Key(ref pk) => { - insert_wrap!(AstElemExt::terminal(Terminal::PkH( - pk.to_pubkeyhash().clone() - ))); + insert_wrap!(AstElemExt::terminal(Terminal::PkH(pk.to_pubkeyhash()))); insert_wrap!(AstElemExt::terminal(Terminal::PkK(pk.clone()))); } Concrete::After(n) => insert_wrap!(AstElemExt::terminal(Terminal::After(n))), @@ -900,12 +895,12 @@ where }; let dissat_probs = |w: f64| -> Vec> { - let mut dissat_set = Vec::new(); - dissat_set.push(Some(dissat_prob.unwrap_or(0 as f64) + w * sat_prob)); - dissat_set.push(Some(w * sat_prob)); - dissat_set.push(dissat_prob); - dissat_set.push(None); - dissat_set + vec![ + Some(dissat_prob.unwrap_or(0 as f64) + w * sat_prob), + Some(w * sat_prob), + dissat_prob, + None, + ] }; let mut l_comp = vec![]; @@ -945,7 +940,7 @@ where let mut best_es = Vec::with_capacity(n); let mut best_ws = Vec::with_capacity(n); - let mut min_value = (0 as usize, f64::INFINITY as f64); + let mut min_value = (0, f64::INFINITY as f64); for (i, ast) in subs.iter().enumerate() { let sp = sat_prob * k_over_n; //Expressions must be dissatisfiable @@ -1013,7 +1008,7 @@ where for k in ret.keys() { debug_assert_eq!(k.dissat_prob, ord_dissat_prob); } - if ret.len() == 0 { + if ret.is_empty() { // The only reason we are discarding elements out of compiler is because // compilations exceeded consensus and standardness limits or are non-malleable. // If there no possible compilations for any policies regardless of dissat @@ -1123,8 +1118,7 @@ where best_compilations(policy_cache, policy, sat_prob, dissat_prob)? .into_iter() .filter(|&(key, _)| { - key.ty.corr.base == types::Base::B - && key.dissat_prob == dissat_prob.and_then(|x| Some(OrdF64(x))) + key.ty.corr.base == types::Base::B && key.dissat_prob == dissat_prob.map(OrdF64) }) .map(|(_, val)| val) .min_by_key(|ext| OrdF64(ext.cost_1d(sat_prob, dissat_prob))) @@ -1149,7 +1143,7 @@ where key.ty.corr.base == basic_type && key.ty.corr.unit && val.ms.ty.mall.dissat == types::Dissat::Unique - && key.dissat_prob == dissat_prob.and_then(|x| Some(OrdF64(x))) + && key.dissat_prob == dissat_prob.map(OrdF64) }) .map(|(_, val)| val) .min_by_key(|ext| OrdF64(ext.cost_1d(sat_prob, dissat_prob)))