use anyhow::{Context, Result};
use confium_transparency::{
entry::{ArtifactType, MerkleEntry},
merkle::{Hash, InclusionProof, MerkleError, MerkleTree},
};
use crate::db::Database;
pub struct MerkleState {
pub tree: MerkleTree,
}
impl MerkleState {
pub fn from_db(db: &Database) -> Result<Self> {
let rows = db
.all_entries_for_rebuild()
.context("loading entries for rebuild")?;
let mut tree = MerkleTree::new();
for row in rows {
let entry = MerkleEntry {
sequence: row.sequence,
timestamp: row.timestamp,
artifact_type: row.artifact_type,
artifact_hash: row.artifact_hash,
metadata: serde_json::Value::Null,
};
tree.append(entry);
}
tracing::info!(count = tree.len(), "rebuilt Merkle tree");
Ok(MerkleState { tree })
}
pub fn append(
&mut self,
leaf: Hash,
artifact_type: ArtifactType,
timestamp: chrono::DateTime<chrono::Utc>,
) -> u64 {
let entry = MerkleEntry {
sequence: 0,
timestamp,
artifact_type,
artifact_hash: leaf,
metadata: serde_json::Value::Null,
};
self.tree.append(entry)
}
pub fn root(&self) -> Hash {
self.tree.root()
}
pub fn len(&self) -> u64 {
self.tree.len() as u64
}
pub fn inclusion_proof(
&self,
sequence: u64,
) -> std::result::Result<InclusionProof, MerkleError> {
self.tree.inclusion_proof(sequence)
}
pub fn consistency_proof(&self, old_size: u64) -> std::result::Result<Vec<Hash>, MerkleError> {
self.tree.consistency_proof(old_size as usize)
}
}