1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
use amplify::Wrapper;
use bitcoin::{OutPoint, Transaction};
use client_side_validation::commit_verify::EmbedCommitVerify;
use client_side_validation::single_use_seals::{Message, SingleUseSeal};
use super::{Error, Witness};
use crate::dbc::{Container, TxCommitment, TxContainer, TxSupplement};
pub struct TxoutSeal<'a, RESOLVER>
where
RESOLVER: TxResolve,
{
seal_definition: OutPoint,
resolver: &'a RESOLVER,
}
impl<'a, RESOLVER> TxoutSeal<'a, RESOLVER>
where
RESOLVER: TxResolve,
{
pub fn new(seal_definition: OutPoint, resolver: &'a RESOLVER) -> Self {
Self {
seal_definition,
resolver,
}
}
}
impl<'a, RESOLVER> SingleUseSeal for TxoutSeal<'a, RESOLVER>
where
RESOLVER: TxResolve,
{
type Witness = Witness;
type Definition = OutPoint;
type Error = Error;
fn close(&self, over: &Message) -> Result<Self::Witness, Self::Error> {
let mut container = self
.resolver
.tx_container(self.seal_definition)
.map_err(|_| Error::ResolverError)?;
let tx_commitment = TxCommitment::embed_commit(&mut container, &over)?;
Ok(Witness(tx_commitment, container.to_proof()))
}
fn verify(
&self,
msg: &Message,
witness: &Self::Witness,
) -> Result<bool, Self::Error> {
let (host, supplement) = self
.resolver
.tx_and_data(self.seal_definition)
.map_err(|_| Error::ResolverError)?;
let found_seals = host
.input
.iter()
.filter(|txin| txin.previous_output == self.seal_definition);
if found_seals.count() != 1 {
Err(Error::ResolverLying)?
}
let container =
TxContainer::reconstruct(&witness.1, &supplement, &host)?;
let commitment = TxCommitment::from_inner(host);
Ok(commitment.verify(&container, &msg)?)
}
}
pub trait TxResolve {
type Error: std::error::Error;
fn tx_container(
&self,
outpoint: OutPoint,
) -> Result<TxContainer, Self::Error>;
fn tx_and_data(
&self,
outpoint: OutPoint,
) -> Result<(Transaction, TxSupplement), Self::Error>;
}