From 428e9787d181a462d06a18b7a45701790cbc0929 Mon Sep 17 00:00:00 2001 From: Shing Him Ng Date: Wed, 27 Nov 2024 07:06:32 -0600 Subject: [PATCH] Explicitly define Ord for NodeInfo --- bitcoin/src/taproot/mod.rs | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/bitcoin/src/taproot/mod.rs b/bitcoin/src/taproot/mod.rs index dbcb65193..88a6f1c55 100644 --- a/bitcoin/src/taproot/mod.rs +++ b/bitcoin/src/taproot/mod.rs @@ -7,7 +7,7 @@ pub mod merkle_branch; pub mod serialized_signature; -use core::cmp::Reverse; +use core::cmp::{Ordering, Reverse}; use core::fmt; use core::iter::FusedIterator; @@ -789,7 +789,7 @@ impl DoubleEndedIterator for LeafNodes<'_> { /// /// You can use [`TaprootSpendInfo::from_node_info`] to a get a [`TaprootSpendInfo`] from the Merkle /// root [`NodeInfo`]. -#[derive(Debug, Clone, PartialOrd, Ord)] +#[derive(Debug, Clone)] pub struct NodeInfo { /// Merkle hash for this node. pub(crate) hash: TapNodeHash, @@ -799,6 +799,24 @@ pub struct NodeInfo { pub(crate) has_hidden_nodes: bool, } +/// Explicitly implement Ord so future changes to NodeInfo (e.g. adding a new field) won't result in +/// potentially changing addresses out from under users +impl Ord for NodeInfo { + fn cmp(&self, other: &Self) -> Ordering { + match self.hash.cmp(&other.hash) { + Ordering::Equal => match self.leaves.cmp(&other.leaves) { + Ordering::Equal => self.has_hidden_nodes.cmp(&other.has_hidden_nodes), + other => other, + }, + other => other, + } + } +} + +impl PartialOrd for NodeInfo { + fn partial_cmp(&self, other: &NodeInfo) -> Option { Some(self.cmp(other)) } +} + impl PartialEq for NodeInfo { fn eq(&self, other: &Self) -> bool { self.hash.eq(&other.hash) } }