urma_core/multipart/
proof.rs1use 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 VerifiedRecord::verify(self.reference.txid, reveal, commit)
65 }
66
67 pub fn check_txid(&self, verified: &VerifiedRecord) -> Result<(), Error> {
68 ensure!(
69 verified.txid == self.reference.txid,
70 "candidate TXID mismatch"
71 );
72 Ok(())
73 }
74
75 pub fn check_hash(&self, verified: &VerifiedRecord) -> Result<(), Error> {
76 ensure!(
77 verified.record_hash == self.reference.record_hash,
78 "record hash differs from the signed manifest reference"
79 );
80 Ok(())
81 }
82}