clvm_utils/
hash_encoder.rs1#![allow(clippy::items_after_statements)]
2
3use clvm_traits::{ClvmEncoder, ToClvm, ToClvmError};
4use clvmr::Atom;
5
6use crate::{tree_hash_atom, tree_hash_pair, TreeHash};
7
8pub trait ToTreeHash {
9 fn tree_hash(&self) -> TreeHash;
10}
11
12impl<T> ToTreeHash for T
13where
14 T: ToClvm<TreeHasher>,
15{
16 fn tree_hash(&self) -> TreeHash {
17 self.to_clvm(&mut TreeHasher).unwrap()
18 }
19}
20
21#[derive(Debug, Clone, Copy)]
22pub struct TreeHasher;
23
24impl ClvmEncoder for TreeHasher {
25 type Node = TreeHash;
26
27 fn encode_atom(&mut self, bytes: Atom<'_>) -> Result<Self::Node, ToClvmError> {
28 Ok(tree_hash_atom(bytes.as_ref()))
29 }
30
31 fn encode_pair(
32 &mut self,
33 first: Self::Node,
34 rest: Self::Node,
35 ) -> Result<Self::Node, ToClvmError> {
36 Ok(tree_hash_pair(first, rest))
37 }
38}
39
40impl ToClvm<TreeHasher> for TreeHash {
41 fn to_clvm(&self, _encoder: &mut TreeHasher) -> Result<TreeHash, ToClvmError> {
42 Ok(*self)
43 }
44}
45
46#[cfg(test)]
47mod tests {
48 use super::*;
49
50 use clvm_traits::ToClvm;
51
52 use crate::{curry_tree_hash, CurriedProgram};
53
54 #[test]
55 fn test_tree_hash() {
56 assert_eq!(
57 hex::encode(().tree_hash()),
58 "4bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459a"
59 );
60 assert_eq!(
61 hex::encode([1, 2, 3].tree_hash()),
62 "bcd55bcd0daebba8cb158547e8480dc968570faf958f1e31a9887d6ae3dba591"
63 );
64 assert_eq!(
65 hex::encode("hello".tree_hash()),
66 "cceeb7a985ecc3dabcb4c8f666cd637f16f008e3c963db6aa6f83a7b288c54ef"
67 );
68 assert_eq!(
69 hex::encode(((1, 2), (3, 4)).tree_hash()),
70 "2824018d148bc6aed0847e2c86aaa8a5407b916169f15b12cea31fa932fc4c8d"
71 );
72
73 assert_eq!(
76 hex::encode([9].tree_hash()),
77 "711d6c4e32c92e53179b199484cf8c897542bc57f2b22582799f9d657eec4699"
78 );
79 }
80
81 #[test]
82 fn test_curry_tree_hash() {
83 let hash_1 = [1, 2, 3].tree_hash();
84 let hash_2 = [4, 5, 6].tree_hash();
85 let hash_3 = [7, 8, 9].tree_hash();
86
87 let manual = curry_tree_hash(hash_1, &[hash_2, hash_3]);
88
89 #[derive(ToClvm)]
90 #[clvm(curry)]
91 struct Args<T> {
92 a: T,
93 b: T,
94 }
95
96 let hash = CurriedProgram {
97 program: hash_1,
98 args: Args {
99 a: hash_2,
100 b: hash_3,
101 },
102 }
103 .tree_hash();
104
105 assert_eq!(hash, manual);
106 }
107}