mithril_stm/merkle_tree/
leaf.rs

1use std::cmp::Ordering;
2
3use blake2::Blake2b;
4use digest::consts::U32;
5use serde::{Deserialize, Serialize};
6
7use crate::bls_multi_signature::BlsVerificationKey;
8use crate::error::MerkleTreeError;
9use crate::{Stake, VerificationKey};
10
11/// The values that are committed in the Merkle Tree.
12/// Namely, a verified `VerificationKey` and its corresponding stake.
13#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize, Hash)]
14pub struct MerkleTreeLeaf(pub BlsVerificationKey, pub Stake);
15
16impl MerkleTreeLeaf {
17    pub(crate) fn from_bytes(bytes: &[u8]) -> Result<Self, MerkleTreeError<Blake2b<U32>>> {
18        let pk =
19            VerificationKey::from_bytes(bytes).map_err(|_| MerkleTreeError::SerializationError)?;
20        let mut u64_bytes = [0u8; 8];
21        u64_bytes.copy_from_slice(&bytes[96..]);
22        let stake = Stake::from_be_bytes(u64_bytes);
23        Ok(MerkleTreeLeaf(pk, stake))
24    }
25    pub(crate) fn to_bytes(self) -> [u8; 104] {
26        let mut result = [0u8; 104];
27        result[..96].copy_from_slice(&self.0.to_bytes());
28        result[96..].copy_from_slice(&self.1.to_be_bytes());
29        result
30    }
31}
32
33impl From<MerkleTreeLeaf> for (VerificationKey, Stake) {
34    fn from(leaf: MerkleTreeLeaf) -> (VerificationKey, Stake) {
35        (leaf.0, leaf.1)
36    }
37}
38
39impl PartialOrd for MerkleTreeLeaf {
40    /// Ordering of MT Values.
41    ///
42    /// First we order by stake, then by key. By having this ordering,
43    /// we have the players with higher stake close together,
44    /// meaning that the probability of having several signatures in the same side of the tree, is higher.
45    /// This allows us to produce a more efficient batch opening of the merkle tree.
46    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
47        Some(std::cmp::Ord::cmp(self, other))
48    }
49}
50
51impl Ord for MerkleTreeLeaf {
52    fn cmp(&self, other: &Self) -> Ordering {
53        self.1.cmp(&other.1).then(self.0.cmp(&other.0))
54    }
55}