From 79d3f7e15c90de9caad70ef72e1fd7f9cd92cc8e Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Tue, 2 Apr 2024 13:18:22 +0000 Subject: [PATCH] sortedmulti: eliminate allocation in constructor_check --- src/descriptor/sortedmulti.rs | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/descriptor/sortedmulti.rs b/src/descriptor/sortedmulti.rs index 58a03bda9..5b7079292 100644 --- a/src/descriptor/sortedmulti.rs +++ b/src/descriptor/sortedmulti.rs @@ -32,15 +32,21 @@ pub struct SortedMultiVec { } impl SortedMultiVec { - fn constructor_check(&self) -> Result<(), Error> { + fn constructor_check(mut self) -> Result { // Check the limits before creating a new SortedMultiVec // For example, under p2sh context the scriptlen can only be // upto 520 bytes. - let term: Terminal = Terminal::Multi(self.inner.clone()); + let term: Terminal = Terminal::Multi(self.inner); let ms = Miniscript::from_ast(term)?; // This would check all the consensus rules for p2sh/p2wsh and // even tapscript in future - Ctx::check_local_validity(&ms).map_err(From::from) + Ctx::check_local_validity(&ms)?; + if let Terminal::Multi(inner) = ms.node { + self.inner = inner; + Ok(self) + } else { + unreachable!() + } } /// Create a new instance of `SortedMultiVec` given a list of keys and the threshold @@ -49,8 +55,7 @@ impl SortedMultiVec { pub fn new(k: usize, pks: Vec) -> Result { let ret = Self { inner: Threshold::new(k, pks).map_err(Error::Threshold)?, phantom: PhantomData }; - ret.constructor_check()?; - Ok(ret) + ret.constructor_check() } /// Parse an expression tree into a SortedMultiVec @@ -66,8 +71,7 @@ impl SortedMultiVec { .translate_by_index(|i| expression::terminal(&tree.args[i + 1], Pk::from_str))?, phantom: PhantomData, }; - ret.constructor_check()?; - Ok(ret) + ret.constructor_check() } /// This will panic if fpk returns an uncompressed key when @@ -85,8 +89,7 @@ impl SortedMultiVec { inner: self.inner.translate_ref(|pk| t.pk(pk))?, phantom: PhantomData, }; - ret.constructor_check().map_err(TranslateErr::OuterError)?; - Ok(ret) + ret.constructor_check().map_err(TranslateErr::OuterError) } /// The threshold value for the multisig.