use crate::proof::verifier::Verifier; use ibc_relayer_types::core::ics23_commitment::error::Error as ProofError; use ics23::commitment_proof::Proof; use ics23::{calculate_existence_root, verify_membership, CommitmentProof, ProofSpec}; use std::marker::PhantomData; #[derive(Clone, Debug)] pub struct Ics23MembershipVerifier<K, V> { spec: ProofSpec, _phantom: PhantomData<(K, V)>, } impl<K, V> Ics23MembershipVerifier<K, V> { pub fn new(spec: ProofSpec) -> Self { Self { spec, _phantom: Default::default(), } } } impl<K, V> Verifier for Ics23MembershipVerifier<K, V> where K: AsRef<[u8]>, V: AsRef<[u8]>, { type Proof = CommitmentProof; type Root = Vec<u8>; type Key = K; type Value = V; type Error = ProofError; fn verify( &self, commitment_proof: &Self::Proof, key: &Self::Key, value: &Self::Value, ) -> Result<Self::Root, Self::Error> { if value.as_ref().is_empty() { return Err(ProofError::empty_verified_value()); } let Some(Proof::Exist(existence_proof)) = &commitment_proof.proof else { return Err(ProofError::invalid_merkle_proof()); }; let root = calculate_existence_root::<ics23::HostFunctionsManager>(existence_proof) .map_err(|_| ProofError::invalid_merkle_proof())?; if !verify_membership::<ics23::HostFunctionsManager>( commitment_proof, &self.spec, &root, key.as_ref(), value.as_ref(), ) { return Err(ProofError::verification_failure()); } Ok(root) } }