Skip to main content

urma_core/multipart/
proof.rs

1use super::{ChildReference, MultipartRecord};
2use crate::{
3    envelope,
4    error::{Error, ensure},
5};
6use bitcoin::{Transaction, Txid, XOnlyPublicKey};
7use sha2::{Digest, Sha256};
8
9#[derive(Clone, Debug)]
10pub struct VerifiedRecord {
11    txid: Txid,
12    author: XOnlyPublicKey,
13    record_hash: [u8; 32],
14    record: Vec<u8>,
15}
16
17impl VerifiedRecord {
18    pub fn verify(
19        expected: Txid,
20        reveal: &Transaction,
21        commit: &Transaction,
22    ) -> Result<Self, Error> {
23        ensure!(reveal.compute_txid() == expected, "candidate TXID mismatch");
24        let proof = envelope::verify_record_proof(reveal, commit)?;
25        Ok(Self {
26            txid: expected,
27            author: proof.author,
28            record_hash: Sha256::digest(&proof.record).into(),
29            record: proof.record,
30        })
31    }
32
33    pub fn txid(&self) -> Txid {
34        self.txid
35    }
36    pub fn author(&self) -> XOnlyPublicKey {
37        self.author
38    }
39    pub fn record_bytes(&self) -> &[u8] {
40        &self.record
41    }
42    pub fn decode(&self) -> Result<MultipartRecord, Error> {
43        MultipartRecord::decode(&self.record)
44    }
45    pub fn reference(&self) -> ChildReference {
46        ChildReference {
47            txid: self.txid,
48            record_hash: self.record_hash,
49        }
50    }
51}
52
53#[derive(Clone, Copy, Debug)]
54pub struct RecordRequest {
55    pub reference: ChildReference,
56}
57
58impl RecordRequest {
59    pub fn verify(
60        &self,
61        reveal: &Transaction,
62        commit: &Transaction,
63    ) -> Result<VerifiedRecord, Error> {
64        let verified = VerifiedRecord::verify(self.reference.txid, reveal, commit)?;
65        self.check(&verified)?;
66        Ok(verified)
67    }
68
69    pub fn check(&self, verified: &VerifiedRecord) -> Result<(), Error> {
70        ensure!(
71            verified.reference() == self.reference,
72            "candidate TXID or record hash mismatch"
73        );
74        Ok(())
75    }
76}