dlc_manager/contract/
mod.rs1use crate::error::Error;
4use crate::ContractId;
5use bitcoin::{SignedAmount, Transaction};
6use dlc_messages::{
7 oracle_msgs::{EventDescriptor, OracleAnnouncement, OracleAttestation},
8 AcceptDlc, SignDlc,
9};
10use dlc_trie::multi_oracle_trie::MultiOracleTrie;
11use dlc_trie::multi_oracle_trie_with_diff::MultiOracleTrieWithDiff;
12use secp256k1_zkp::PublicKey;
13#[cfg(feature = "use-serde")]
14use serde::{Deserialize, Serialize};
15use signed_contract::SignedContract;
16
17use self::utils::unordered_equal;
18
19pub mod accepted_contract;
20pub mod contract_info;
21pub mod contract_input;
22pub mod enum_descriptor;
23pub mod numerical_descriptor;
24pub mod offered_contract;
25pub mod ser;
26pub mod signed_contract;
27pub(crate) mod utils;
28
29#[derive(Clone)]
30pub enum Contract {
32 Offered(offered_contract::OfferedContract),
34 Accepted(accepted_contract::AcceptedContract),
36 Signed(signed_contract::SignedContract),
38 Confirmed(signed_contract::SignedContract),
40 PreClosed(PreClosedContract),
42 Closed(ClosedContract),
44 Refunded(signed_contract::SignedContract),
46 FailedAccept(FailedAcceptContract),
48 FailedSign(FailedSignContract),
50 Rejected(offered_contract::OfferedContract),
52}
53
54impl std::fmt::Debug for Contract {
55 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
56 let state = match self {
57 Contract::Offered(_) => "offered",
58 Contract::Accepted(_) => "accepted",
59 Contract::Signed(_) => "signed",
60 Contract::Confirmed(_) => "confirmed",
61 Contract::PreClosed(_) => "pre-closed",
62 Contract::Closed(_) => "closed",
63 Contract::Refunded(_) => "refunded",
64 Contract::FailedAccept(_) => "failed accept",
65 Contract::FailedSign(_) => "failed sign",
66 Contract::Rejected(_) => "rejected",
67 };
68 f.debug_struct("Contract").field("state", &state).finish()
69 }
70}
71
72impl Contract {
73 pub fn get_id(&self) -> ContractId {
76 match self {
77 Contract::Offered(o) | Contract::Rejected(o) => o.id,
78 Contract::Accepted(o) => o.get_contract_id(),
79 Contract::Signed(o) | Contract::Confirmed(o) | Contract::Refunded(o) => {
80 o.accepted_contract.get_contract_id()
81 }
82 Contract::FailedAccept(c) => c.offered_contract.id,
83 Contract::FailedSign(c) => c.accepted_contract.get_contract_id(),
84 Contract::PreClosed(c) => c.signed_contract.accepted_contract.get_contract_id(),
85 Contract::Closed(c) => c.contract_id,
86 }
87 }
88
89 pub fn get_temporary_id(&self) -> ContractId {
91 match self {
92 Contract::Offered(o) | Contract::Rejected(o) => o.id,
93 Contract::Accepted(o) => o.offered_contract.id,
94 Contract::Signed(o) | Contract::Confirmed(o) | Contract::Refunded(o) => {
95 o.accepted_contract.offered_contract.id
96 }
97 Contract::FailedAccept(c) => c.offered_contract.id,
98 Contract::FailedSign(c) => c.accepted_contract.offered_contract.id,
99 Contract::PreClosed(c) => c.signed_contract.accepted_contract.offered_contract.id,
100 Contract::Closed(c) => c.temporary_contract_id,
101 }
102 }
103
104 pub fn get_counter_party_id(&self) -> PublicKey {
106 match self {
107 Contract::Offered(o) | Contract::Rejected(o) => o.counter_party,
108 Contract::Accepted(a) => a.offered_contract.counter_party,
109 Contract::Signed(s) | Contract::Confirmed(s) | Contract::Refunded(s) => {
110 s.accepted_contract.offered_contract.counter_party
111 }
112 Contract::PreClosed(c) => {
113 c.signed_contract
114 .accepted_contract
115 .offered_contract
116 .counter_party
117 }
118 Contract::Closed(c) => c.counter_party_id,
119 Contract::FailedAccept(f) => f.offered_contract.counter_party,
120 Contract::FailedSign(f) => f.accepted_contract.offered_contract.counter_party,
121 }
122 }
123}
124
125#[derive(Clone)]
127pub struct FailedAcceptContract {
128 pub offered_contract: offered_contract::OfferedContract,
130 pub accept_message: AcceptDlc,
132 pub error_message: String,
134}
135
136#[derive(Clone)]
138pub struct FailedSignContract {
139 pub accepted_contract: accepted_contract::AcceptedContract,
141 pub sign_message: SignDlc,
143 pub error_message: String,
145}
146
147#[derive(Clone)]
149pub struct PreClosedContract {
150 pub signed_contract: SignedContract,
152 pub attestations: Option<Vec<OracleAttestation>>,
154 pub signed_cet: Transaction,
156}
157
158#[derive(Clone)]
160pub struct ClosedContract {
161 pub attestations: Option<Vec<OracleAttestation>>,
163 pub signed_cet: Option<Transaction>,
165 pub contract_id: ContractId,
167 pub temporary_contract_id: ContractId,
169 pub counter_party_id: PublicKey,
171 pub pnl: SignedAmount,
173}
174
175#[derive(Clone)]
178pub enum AdaptorInfo {
179 Enum,
181 Numerical(MultiOracleTrie),
183 NumericalWithDifference(MultiOracleTrieWithDiff),
186}
187
188#[derive(Clone, Debug)]
190#[cfg_attr(
191 feature = "use-serde",
192 derive(Serialize, Deserialize),
193 serde(rename_all = "camelCase")
194)]
195pub enum ContractDescriptor {
196 Enum(enum_descriptor::EnumDescriptor),
198 Numerical(numerical_descriptor::NumericalDescriptor),
200}
201
202impl ContractDescriptor {
203 pub fn get_oracle_params(&self) -> Option<numerical_descriptor::DifferenceParams> {
205 match self {
206 ContractDescriptor::Enum(_) => None,
207 ContractDescriptor::Numerical(n) => n.difference_params.clone(),
208 }
209 }
210
211 pub fn validate(
214 &self,
215 announcements: &Vec<OracleAnnouncement>,
216 ) -> Result<(), crate::error::Error> {
217 let first = announcements
218 .first()
219 .expect("to have at least one element.");
220 match &first.oracle_event.event_descriptor {
221 EventDescriptor::EnumEvent(ee) => {
222 for announcement in announcements {
223 match &announcement.oracle_event.event_descriptor {
224 EventDescriptor::EnumEvent(enum_desc) => {
225 if !unordered_equal(&ee.outcomes, &enum_desc.outcomes) {
226 return Err(Error::InvalidParameters(
227 "Oracles don't have same enum outcomes.".to_string(),
228 ));
229 }
230 }
231 _ => {
232 return Err(Error::InvalidParameters(
233 "Expected enum event descriptor.".to_string(),
234 ))
235 }
236 }
237 }
238 match self {
239 ContractDescriptor::Enum(ed) => ed.validate(ee),
240 _ => Err(Error::InvalidParameters(
241 "Event descriptor from contract and oracle differ.".to_string(),
242 )),
243 }
244 }
245 EventDescriptor::DigitDecompositionEvent(_) => match self {
246 ContractDescriptor::Numerical(n) => {
247 let min_nb_digits = n.oracle_numeric_infos.get_min_nb_digits();
248 let max_value = n
249 .oracle_numeric_infos
250 .base
251 .checked_pow(min_nb_digits as u32)
252 .ok_or_else(|| {
253 Error::InvalidParameters("Could not compute max value".to_string())
254 })?;
255 n.validate((max_value - 1) as u64)
256 }
257 _ => Err(Error::InvalidParameters(
258 "Event descriptor from contract and oracle differ.".to_string(),
259 )),
260 },
261 }
262 }
263}