From 07774917c24da4dff86322e58e24f53d862bbcc7 Mon Sep 17 00:00:00 2001 From: Martin Habovstiak Date: Tue, 10 Aug 2021 10:36:51 +0200 Subject: [PATCH] Use get_or_insert_with in segwit_cache This refactors the code to make it possible to use `get_or_insert_with` instead of unwrapping in `segwit_cache()`. To achieve it `common_cache` is refactored into two functions: one taking only the required borrows and the original calling the new one. `segwit_cache` then calls the new function so that borrows are OK. Apart from removing unwrap, this avoids calling `common_cache` multiple times. --- src/util/sighash.rs | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/src/util/sighash.rs b/src/util/sighash.rs index 93101bd4..b00c9588 100644 --- a/src/util/sighash.rs +++ b/src/util/sighash.rs @@ -549,9 +549,13 @@ impl> SigHashCache { Ok(SigHash::from_engine(enc)) } + #[inline] fn common_cache(&mut self) -> &CommonCache { - let tx = &self.tx; - self.common_cache.get_or_insert_with(|| { + Self::common_cache_minimal_borrow(&mut self.common_cache, &self.tx) + } + + fn common_cache_minimal_borrow<'a>(common_cache: &'a mut Option, tx: &R) -> &'a CommonCache { + common_cache.get_or_insert_with(|| { let mut enc_prevouts = sha256::Hash::engine(); let mut enc_sequences = sha256::Hash::engine(); for txin in tx.input.iter() { @@ -575,21 +579,22 @@ impl> SigHashCache { } fn segwit_cache(&mut self) -> &SegwitCache { - if self.segwit_cache.is_none() { - let cache = SegwitCache { + let common_cache = &mut self.common_cache; + let tx = &self.tx; + self.segwit_cache.get_or_insert_with(|| { + let common_cache = Self::common_cache_minimal_borrow(common_cache, tx); + SegwitCache { prevouts: sha256d::Hash::from_inner( - sha256::Hash::hash(&self.common_cache().prevouts).into_inner(), + sha256::Hash::hash(&common_cache.prevouts).into_inner(), ), sequences: sha256d::Hash::from_inner( - sha256::Hash::hash(&self.common_cache().sequences).into_inner(), + sha256::Hash::hash(&common_cache.sequences).into_inner(), ), outputs: sha256d::Hash::from_inner( - sha256::Hash::hash(&self.common_cache().outputs).into_inner(), + sha256::Hash::hash(&common_cache.outputs).into_inner(), ), - }; - self.segwit_cache = Some(cache); - } - self.segwit_cache.as_ref().unwrap() // safe to unwrap because we checked is_none() + } + }) } fn taproot_cache(&mut self, prevouts: &[TxOut]) -> &TaprootCache {