mithril_common/entities/
cardano_transactions_set_proof.rs1use crate::StdResult;
2use crate::crypto_helper::{MKMapProof, ProtocolMkProof};
3use crate::entities::TransactionHash;
4
5use super::BlockRange;
6
7#[derive(Clone, Debug, PartialEq)]
9pub struct CardanoTransactionsSetProof {
10 pub(crate) transactions_hashes: Vec<TransactionHash>,
12
13 pub(crate) transactions_proof: ProtocolMkProof,
15}
16
17impl CardanoTransactionsSetProof {
18 pub fn new<T: Into<MKMapProof<BlockRange>>>(
20 transactions_hashes: Vec<TransactionHash>,
21 transactions_proof: T,
22 ) -> Self {
23 Self {
24 transactions_hashes,
25 transactions_proof: ProtocolMkProof::new(transactions_proof.into()),
26 }
27 }
28
29 pub fn merkle_root(&self) -> String {
31 self.transactions_proof.compute_root().to_hex()
32 }
33
34 pub fn transactions_hashes(&self) -> &[TransactionHash] {
36 &self.transactions_hashes
37 }
38
39 pub fn verify(&self) -> StdResult<()> {
41 self.transactions_proof.verify()?;
42 for hash in &self.transactions_hashes {
43 self.transactions_proof.contains(&hash.to_owned().into())?;
44 }
45
46 Ok(())
47 }
48}
49
50#[cfg(test)]
51mod tests {
52 use crate::crypto_helper::MKTreeStoreInMemory;
53 use crate::entities::BlockNumber;
54 use crate::test::entities_extensions::CardanoTransactionsSetProofTestExtension;
55
56 use super::*;
57
58 #[test]
59 fn should_verify_where_all_hashes_are_contained_in_the_proof() {
60 let leaves = vec![
61 (BlockNumber(0), "tx-1".to_string()),
62 (BlockNumber(1), "tx-2".to_string()),
63 (BlockNumber(1), "tx-3".to_string()),
64 (BlockNumber(10), "tx-4".to_string()),
65 (BlockNumber(20), "tx-5".to_string()),
66 (BlockNumber(22), "tx-6".to_string()),
67 ];
68 let proof =
69 CardanoTransactionsSetProof::from_leaves::<MKTreeStoreInMemory>(&leaves).unwrap();
70
71 proof.verify().expect("The proof should be valid");
72 }
73
74 #[test]
75 fn shouldnt_verify_where_at_least_one_hash_is_not_contained_in_the_proof() {
76 let leaves = vec![
77 (BlockNumber(0), "tx-1".to_string()),
78 (BlockNumber(1), "tx-2".to_string()),
79 (BlockNumber(1), "tx-3".to_string()),
80 (BlockNumber(10), "tx-4".to_string()),
81 (BlockNumber(20), "tx-5".to_string()),
82 (BlockNumber(22), "tx-6".to_string()),
83 ];
84 let proof =
85 CardanoTransactionsSetProof::from_leaves::<MKTreeStoreInMemory>(&leaves).unwrap();
86 let mut transactions_hashes_tampered = proof.transactions_hashes().to_vec();
87 transactions_hashes_tampered.push("tx-123".to_string());
88 let proof = CardanoTransactionsSetProof {
89 transactions_hashes: transactions_hashes_tampered,
90 ..proof
91 };
92
93 proof.verify().expect_err("The proof should be invalid");
94 }
95}