63 lines
1.6 KiB
Rust
63 lines
1.6 KiB
Rust
|
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)
|
||
|
}
|
||
|
}
|