diff --git a/zebra-chain/src/orchard/tree.rs b/zebra-chain/src/orchard/tree.rs index 42ad806c9ad..eb7c1dfd989 100644 --- a/zebra-chain/src/orchard/tree.rs +++ b/zebra-chain/src/orchard/tree.rs @@ -335,7 +335,8 @@ impl NoteCommitmentTree { .cached_root .write() .expect("a thread that previously held exclusive lock access panicked"); - match *write_root { + let read_root = write_root.as_ref().cloned(); + match read_root { // Another thread got write access first, return cached root. Some(root) => root, None => { diff --git a/zebra-chain/src/sapling/tree.rs b/zebra-chain/src/sapling/tree.rs index b0cfb302b21..628039a1ed8 100644 --- a/zebra-chain/src/sapling/tree.rs +++ b/zebra-chain/src/sapling/tree.rs @@ -340,7 +340,8 @@ impl NoteCommitmentTree { .cached_root .write() .expect("a thread that previously held exclusive lock access panicked"); - match *write_root { + let read_root = write_root.as_ref().cloned(); + match read_root { // Another thread got write access first, return cached root. Some(root) => root, None => { diff --git a/zebra-chain/src/sprout/tree.rs b/zebra-chain/src/sprout/tree.rs index ad99f9f968b..da01af506f5 100644 --- a/zebra-chain/src/sprout/tree.rs +++ b/zebra-chain/src/sprout/tree.rs @@ -274,7 +274,8 @@ impl NoteCommitmentTree { .cached_root .write() .expect("a thread that previously held exclusive lock access panicked"); - match *write_root { + let read_root = write_root.as_ref().cloned(); + match read_root { // Another thread got write access first, return cached root. Some(root) => root, None => { diff --git a/zebra-state/src/service/chain_tip.rs b/zebra-state/src/service/chain_tip.rs index bddde612daa..370385225ae 100644 --- a/zebra-state/src/service/chain_tip.rs +++ b/zebra-state/src/service/chain_tip.rs @@ -195,12 +195,18 @@ impl ChainTipSender { // a read-lock being created and living beyond the `self.sender.send(..)` call. If that // happens, the `send` method will attempt to obtain a write-lock and will dead-lock. // Without the binding, the guard is dropped at the end of the expression. - let needs_update = match (new_tip.as_ref(), self.sender.borrow().as_ref()) { + let active_hash = self + .sender + .borrow() + .as_ref() + .map(|active_value| active_value.hash); + + let needs_update = match (new_tip.as_ref(), active_hash) { // since the blocks have been contextually validated, // we know their hashes cover all the block data - (Some(new_tip), Some(active_value)) => new_tip.hash != active_value.hash, + (Some(new_tip), Some(active_hash)) => new_tip.hash != active_hash, (Some(_new_tip), None) => true, - (None, _active_value) => false, + (None, _active_value_hash) => false, }; if needs_update {