ddk_manager/contract/
mod.rs1use crate::error::Error;
4use crate::ContractId;
5use bitcoin::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;
16use std::fmt::Write;
17
18use self::utils::unordered_equal;
19
20pub mod accepted_contract;
21pub mod contract_info;
22pub mod contract_input;
23pub mod enum_descriptor;
24pub mod numerical_descriptor;
25pub mod offered_contract;
26pub mod ser;
27pub mod signed_contract;
28pub(crate) mod utils;
29
30#[derive(Clone)]
31pub enum Contract {
33 Offered(offered_contract::OfferedContract),
35 Accepted(accepted_contract::AcceptedContract),
37 Signed(signed_contract::SignedContract),
39 Confirmed(signed_contract::SignedContract),
41 PreClosed(PreClosedContract),
43 Closed(ClosedContract),
45 Refunded(signed_contract::SignedContract),
47 FailedAccept(FailedAcceptContract),
49 FailedSign(FailedSignContract),
51 Rejected(offered_contract::OfferedContract),
53}
54
55impl std::fmt::Debug for Contract {
56 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
57 let state = match self {
58 Contract::Offered(_) => "offered",
59 Contract::Accepted(_) => "accepted",
60 Contract::Signed(_) => "signed",
61 Contract::Confirmed(_) => "confirmed",
62 Contract::PreClosed(_) => "pre-closed",
63 Contract::Closed(_) => "closed",
64 Contract::Refunded(_) => "refunded",
65 Contract::FailedAccept(_) => "failed accept",
66 Contract::FailedSign(_) => "failed sign",
67 Contract::Rejected(_) => "rejected",
68 };
69 f.debug_struct("Contract").field("state", &state).finish()
70 }
71}
72
73impl Contract {
74 pub fn get_id(&self) -> ContractId {
77 match self {
78 Contract::Offered(o) | Contract::Rejected(o) => o.id,
79 Contract::Accepted(o) => o.get_contract_id(),
80 Contract::Signed(o) | Contract::Confirmed(o) | Contract::Refunded(o) => {
81 o.accepted_contract.get_contract_id()
82 }
83 Contract::FailedAccept(c) => c.offered_contract.id,
84 Contract::FailedSign(c) => c.accepted_contract.get_contract_id(),
85 Contract::PreClosed(c) => c.signed_contract.accepted_contract.get_contract_id(),
86 Contract::Closed(c) => c.contract_id,
87 }
88 }
89
90 pub fn get_id_string(&self) -> String {
92 let mut string_id = String::with_capacity(32 * 2 + 2);
93 string_id.push_str("0x");
94 let id = self.get_id();
95 for i in &id {
96 write!(string_id, "{:02x}", i).unwrap();
97 }
98
99 string_id
100 }
101
102 pub fn get_temporary_id(&self) -> ContractId {
104 match self {
105 Contract::Offered(o) | Contract::Rejected(o) => o.id,
106 Contract::Accepted(o) => o.offered_contract.id,
107 Contract::Signed(o) | Contract::Confirmed(o) | Contract::Refunded(o) => {
108 o.accepted_contract.offered_contract.id
109 }
110 Contract::FailedAccept(c) => c.offered_contract.id,
111 Contract::FailedSign(c) => c.accepted_contract.offered_contract.id,
112 Contract::PreClosed(c) => c.signed_contract.accepted_contract.offered_contract.id,
113 Contract::Closed(c) => c.temporary_contract_id,
114 }
115 }
116
117 pub fn get_counter_party_id(&self) -> PublicKey {
119 match self {
120 Contract::Offered(o) | Contract::Rejected(o) => o.counter_party,
121 Contract::Accepted(a) => a.offered_contract.counter_party,
122 Contract::Signed(s) | Contract::Confirmed(s) | Contract::Refunded(s) => {
123 s.accepted_contract.offered_contract.counter_party
124 }
125 Contract::PreClosed(c) => {
126 c.signed_contract
127 .accepted_contract
128 .offered_contract
129 .counter_party
130 }
131 Contract::Closed(c) => c.counter_party_id,
132 Contract::FailedAccept(f) => f.offered_contract.counter_party,
133 Contract::FailedSign(f) => f.accepted_contract.offered_contract.counter_party,
134 }
135 }
136}
137
138#[derive(Clone)]
140pub struct FailedAcceptContract {
141 pub offered_contract: offered_contract::OfferedContract,
143 pub accept_message: AcceptDlc,
145 pub error_message: String,
147}
148
149#[derive(Clone)]
151pub struct FailedSignContract {
152 pub accepted_contract: accepted_contract::AcceptedContract,
154 pub sign_message: SignDlc,
156 pub error_message: String,
158}
159
160#[derive(Clone)]
162pub struct PreClosedContract {
163 pub signed_contract: SignedContract,
165 pub attestations: Option<Vec<OracleAttestation>>,
167 pub signed_cet: Transaction,
169}
170
171#[derive(Clone)]
173pub struct ClosedContract {
174 pub attestations: Option<Vec<OracleAttestation>>,
176 pub signed_cet: Option<Transaction>,
178 pub contract_id: ContractId,
180 pub temporary_contract_id: ContractId,
182 pub counter_party_id: PublicKey,
184 pub pnl: i64,
186}
187
188#[derive(Clone)]
191pub enum AdaptorInfo {
192 Enum,
194 Numerical(MultiOracleTrie),
196 NumericalWithDifference(MultiOracleTrieWithDiff),
199}
200
201#[derive(Clone, Debug)]
203#[cfg_attr(
204 feature = "use-serde",
205 derive(Serialize, Deserialize),
206 serde(rename_all = "camelCase")
207)]
208pub enum ContractDescriptor {
209 Enum(enum_descriptor::EnumDescriptor),
211 Numerical(numerical_descriptor::NumericalDescriptor),
213}
214
215impl ContractDescriptor {
216 pub fn get_oracle_params(&self) -> Option<numerical_descriptor::DifferenceParams> {
218 match self {
219 ContractDescriptor::Enum(_) => None,
220 ContractDescriptor::Numerical(n) => n.difference_params.clone(),
221 }
222 }
223
224 pub fn validate(
227 &self,
228 announcements: &Vec<OracleAnnouncement>,
229 ) -> Result<(), crate::error::Error> {
230 let first = announcements
231 .first()
232 .expect("to have at least one element.");
233 match &first.oracle_event.event_descriptor {
234 EventDescriptor::EnumEvent(ee) => {
235 for announcement in announcements {
236 match &announcement.oracle_event.event_descriptor {
237 EventDescriptor::EnumEvent(enum_desc) => {
238 if !unordered_equal(&ee.outcomes, &enum_desc.outcomes) {
239 return Err(Error::InvalidParameters(
240 "Oracles don't have same enum outcomes.".to_string(),
241 ));
242 }
243 }
244 _ => {
245 return Err(Error::InvalidParameters(
246 "Expected enum event descriptor.".to_string(),
247 ))
248 }
249 }
250 }
251 match self {
252 ContractDescriptor::Enum(ed) => ed.validate(ee),
253 _ => Err(Error::InvalidParameters(
254 "Event descriptor from contract and oracle differ.".to_string(),
255 )),
256 }
257 }
258 EventDescriptor::DigitDecompositionEvent(_) => match self {
259 ContractDescriptor::Numerical(n) => {
260 let min_nb_digits = n.oracle_numeric_infos.get_min_nb_digits();
261 let max_value = n
262 .oracle_numeric_infos
263 .base
264 .checked_pow(min_nb_digits as u32)
265 .ok_or_else(|| {
266 Error::InvalidParameters("Could not compute max value".to_string())
267 })?;
268 n.validate((max_value - 1) as u64)
269 }
270 _ => Err(Error::InvalidParameters(
271 "Event descriptor from contract and oracle differ.".to_string(),
272 )),
273 },
274 }
275 }
276}