use std::error::Error;
use bitcoin::Transaction as Tx;
use strict_encoding::{StrictDumb, StrictEncode};
use crate::commit_verify::mpc::{self, Message, ProtocolId};
use crate::LIB_NAME_BPCORE;
mod dbc {
pub use crate::dbc::Proof;
}
#[derive(Clone, Eq, PartialEq, Debug, Display, Error, From)]
#[display(inner)]
#[cfg_attr(
feature = "serde",
derive(Serialize, Deserialize),
serde(crate = "serde_crate", rename_all = "camelCase")
)]
pub enum VerifyError<E: Error> {
#[display(inner)]
Dbc(E),
#[from]
Mpc(mpc::InvalidProof),
}
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
#[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)]
#[strict_type(lib = LIB_NAME_BPCORE)]
#[cfg_attr(
feature = "serde",
derive(Serialize, Deserialize),
serde(crate = "serde_crate", rename_all = "camelCase")
)]
pub struct Anchor<D: dbc::Proof> {
pub mpc_proof: mpc::MerkleProof,
pub dbc_proof: D,
}
impl<D: dbc::Proof> Anchor<D> {
pub fn new(mpc_proof: mpc::MerkleProof, dbc_proof: D) -> Self {
Self {
mpc_proof,
dbc_proof,
}
}
}
impl<D: dbc::Proof> Anchor<D> {
pub fn verify(
&self,
protocol_id: impl Into<ProtocolId>,
message: impl Into<Message>,
tx: &Tx,
) -> Result<mpc::Commitment, VerifyError<D::Error>> {
let mpc_commitment = self.convolve(protocol_id, message)?;
self.dbc_proof
.verify(&mpc_commitment, tx)
.map_err(VerifyError::Dbc)?;
Ok(mpc_commitment)
}
pub fn convolve(
&self,
protocol_id: impl Into<ProtocolId>,
message: impl Into<Message>,
) -> Result<mpc::Commitment, mpc::InvalidProof> {
self.mpc_proof.convolve(protocol_id.into(), message.into())
}
}