confium_log_server/
merkle.rs1use anyhow::{Context, Result};
10use confium_transparency::{
11 entry::{ArtifactType, MerkleEntry},
12 merkle::{Hash, InclusionProof, MerkleError, MerkleTree},
13};
14
15use crate::db::Database;
16
17pub struct MerkleState {
18 pub tree: MerkleTree,
19}
20
21impl MerkleState {
22 pub fn from_db(db: &Database) -> Result<Self> {
30 let rows = db
31 .all_entries_for_rebuild()
32 .context("loading entries for rebuild")?;
33 let mut tree = MerkleTree::new();
34 for row in rows {
35 let entry = MerkleEntry {
36 sequence: row.sequence,
37 timestamp: row.timestamp,
38 artifact_type: row.artifact_type,
39 artifact_hash: row.artifact_hash,
40 metadata: serde_json::Value::Null,
41 };
42 tree.append(entry);
43 }
44 tracing::info!(count = tree.len(), "rebuilt Merkle tree");
45 Ok(MerkleState { tree })
46 }
47
48 pub fn append(
52 &mut self,
53 leaf: Hash,
54 artifact_type: ArtifactType,
55 timestamp: chrono::DateTime<chrono::Utc>,
56 ) -> u64 {
57 let entry = MerkleEntry {
58 sequence: 0,
59 timestamp,
60 artifact_type,
61 artifact_hash: leaf,
62 metadata: serde_json::Value::Null,
63 };
64 self.tree.append(entry)
65 }
66
67 pub fn root(&self) -> Hash {
68 self.tree.root()
69 }
70
71 pub fn len(&self) -> u64 {
72 self.tree.len() as u64
73 }
74
75 pub fn inclusion_proof(
76 &self,
77 sequence: u64,
78 ) -> std::result::Result<InclusionProof, MerkleError> {
79 self.tree.inclusion_proof(sequence)
80 }
81
82 pub fn consistency_proof(&self, old_size: u64) -> std::result::Result<Vec<Hash>, MerkleError> {
83 self.tree.consistency_proof(old_size as usize)
84 }
85}