use bitcoin::Transaction as Tx;
use strict_encoding::{StrictDeserialize, StrictDumb, StrictSerialize};
use crate::commit_verify::mpc::Commitment;
use crate::commit_verify::{ConvolveVerifyError, EmbedVerifyError};
use crate::dbc::opret::{OpretError, OpretProof};
use crate::dbc::tapret::TapretProof;
use crate::dbc::{self, Method};
use crate::LIB_NAME_RGB_LOGIC;
#[derive(Copy, Clone, Eq, PartialEq, Debug, Display, Error)]
#[cfg_attr(
feature = "serde",
derive(Serialize, Deserialize),
serde(crate = "serde_crate", rename_all = "camelCase")
)]
#[display(doc_comments)]
pub enum DbcError {
NoOpretOutput,
InvalidOpretScript,
CommitmentMismatch,
UnrestorableProof,
ProofMismatch,
ImpossibleMessage,
InvalidProof,
}
#[derive(Clone, Eq, PartialEq, Debug, From)]
#[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)]
#[strict_type(lib = LIB_NAME_RGB_LOGIC, tags = custom, dumb = Self::Tapret(strict_dumb!()))]
#[cfg_attr(
feature = "serde",
derive(Serialize, Deserialize),
serde(crate = "serde_crate", rename_all = "camelCase", untagged)
)]
pub enum DbcProof {
#[from]
#[strict_type(tag = 0x01)]
Tapret(TapretProof),
#[from]
#[strict_type(tag = 0x02)]
Opret(OpretProof),
}
impl StrictSerialize for DbcProof {}
impl StrictDeserialize for DbcProof {}
impl dbc::Proof for DbcProof {
type Error = DbcError;
fn method(&self) -> Method {
match self {
DbcProof::Tapret(_) => Method::TapretFirst,
DbcProof::Opret(_) => Method::OpretFirst,
}
}
fn verify(&self, msg: &Commitment, tx: &Tx) -> Result<(), Self::Error> {
match self {
DbcProof::Tapret(tapret) => tapret.verify(msg, tx).map_err(|err| match err {
ConvolveVerifyError::CommitmentMismatch => DbcError::CommitmentMismatch,
ConvolveVerifyError::ImpossibleMessage => DbcError::ImpossibleMessage,
ConvolveVerifyError::InvalidProof => DbcError::InvalidProof,
}),
DbcProof::Opret(opret) => opret.verify(msg, tx).map_err(|err| match err {
EmbedVerifyError::CommitmentMismatch => DbcError::CommitmentMismatch,
EmbedVerifyError::InvalidMessage(OpretError::NoOpretOutput) => {
DbcError::NoOpretOutput
}
EmbedVerifyError::InvalidMessage(OpretError::InvalidOpretScript) => {
DbcError::InvalidOpretScript
}
EmbedVerifyError::InvalidProof => DbcError::UnrestorableProof,
EmbedVerifyError::ProofMismatch => DbcError::ProofMismatch,
}),
}
}
}
pub type EAnchor = dbc::Anchor<DbcProof>;