1use crate::contract::accepted_contract::AcceptedContract;
5use crate::contract::contract_info::ContractInfo;
6use crate::contract::enum_descriptor::EnumDescriptor;
7use crate::contract::numerical_descriptor::{DifferenceParams, NumericalDescriptor};
8use crate::contract::offered_contract::OfferedContract;
9use crate::contract::signed_contract::SignedContract;
10use crate::contract::AdaptorInfo;
11use crate::contract::{
12 ClosedContract, ContractDescriptor, FailedAcceptContract, FailedSignContract, PreClosedContract,
13};
14use crate::payout_curve::{
15 HyperbolaPayoutCurvePiece, PayoutFunction, PayoutFunctionPiece, PayoutPoint,
16 PolynomialPayoutCurvePiece, RoundingInterval, RoundingIntervals,
17};
18use crate::KeysId;
19use bitcoin::Amount;
20use ddk_dlc::DlcTransactions;
21use ddk_messages::impl_dlc_writeable;
22use ddk_messages::ser_impls::{
23 read_ecdsa_adaptor_signatures, read_option_cb, read_usize, read_vec, read_vec_cb,
24 write_ecdsa_adaptor_signatures, write_option_cb, write_usize, write_vec, write_vec_cb,
25};
26use ddk_trie::digit_trie::{DigitNodeData, DigitTrieDump};
27use ddk_trie::multi_oracle_trie::{MultiOracleTrie, MultiOracleTrieDump};
28use ddk_trie::multi_oracle_trie_with_diff::{MultiOracleTrieWithDiff, MultiOracleTrieWithDiffDump};
29use ddk_trie::multi_trie::{MultiTrieDump, MultiTrieNodeData, TrieNodeInfo};
30use ddk_trie::{OracleNumericInfo, RangeInfo};
31use lightning::io::Read;
32use lightning::ln::msgs::DecodeError;
33use lightning::util::ser::{Readable, Writeable, Writer};
34
35pub trait Serializable
37where
38 Self: Sized,
39{
40 fn serialize(&self) -> Result<Vec<u8>, lightning::io::Error>;
42 fn deserialize<R: Read>(reader: &mut R) -> Result<Self, DecodeError>;
44}
45
46impl<T> Serializable for T
47where
48 T: Writeable + Readable,
49{
50 fn serialize(&self) -> Result<Vec<u8>, lightning::io::Error> {
51 let mut buffer = Vec::new();
52 self.write(&mut buffer)?;
53 Ok(buffer)
54 }
55
56 fn deserialize<R: Read>(reader: &mut R) -> Result<Self, DecodeError> {
57 Readable::read(reader)
58 }
59}
60
61impl_dlc_writeable!(PayoutPoint, { (event_outcome, writeable), (outcome_payout, writeable), (extra_precision, writeable) });
62impl_dlc_writeable_enum!(
63 PayoutFunctionPiece,
64 (0, PolynomialPayoutCurvePiece),
65 (1, HyperbolaPayoutCurvePiece);;;
66);
67impl_dlc_writeable!(RoundingInterval, { (begin_interval, writeable), (rounding_mod, writeable) });
68impl_dlc_writeable!(PayoutFunction, { (payout_function_pieces, vec) });
69impl_dlc_writeable!(NumericalDescriptor, { (payout_function, writeable), (rounding_intervals, writeable), (difference_params, option), (oracle_numeric_infos, {cb_writeable, oracle_params::write, oracle_params::read}) });
70impl_dlc_writeable!(PolynomialPayoutCurvePiece, { (payout_points, vec) });
71impl_dlc_writeable!(RoundingIntervals, { (intervals, vec) });
72impl_dlc_writeable!(DifferenceParams, { (max_error_exp, usize), (min_support_exp, usize), (maximize_coverage, writeable) });
73impl_dlc_writeable!(HyperbolaPayoutCurvePiece, {
74 (left_end_point, writeable),
75 (right_end_point, writeable),
76 (use_positive_piece, writeable),
77 (translate_outcome, float),
78 (translate_payout, float),
79 (a, float),
80 (b, float),
81 (c, float),
82 (d, float)
83});
84impl_dlc_writeable_enum!(ContractDescriptor, (0, Enum), (1, Numerical);;;);
85impl_dlc_writeable!(ContractInfo, { (contract_descriptor, writeable), (oracle_announcements, vec), (threshold, usize)});
86impl_dlc_writeable!(EnumDescriptor, {
87 (
88 outcome_payouts,
89 {vec_cb, ddk_messages::ser_impls::enum_payout::write, ddk_messages::ser_impls::enum_payout::read}
90 )
91});
92impl Writeable for OfferedContract {
93 fn write<W: Writer>(&self, w: &mut W) -> Result<(), lightning::io::Error> {
94 self.id.write(w)?;
95 self.is_offer_party.write(w)?;
96 write_vec(&self.contract_info, w)?;
97 ddk_messages::ser_impls::party_params::write(&self.offer_params, w)?;
98 self.total_collateral.write(w)?;
99 write_vec(&self.funding_inputs, w)?;
100 self.fund_output_serial_id.write(w)?;
101 self.fee_rate_per_vb.write(w)?;
102 self.cet_locktime.write(w)?;
103 self.refund_locktime.write(w)?;
104 self.contract_flags.write(w)?;
105 self.counter_party.write(w)?;
106 self.keys_id.write(w)?;
107 Ok(())
108 }
109}
110
111impl Readable for OfferedContract {
112 fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
113 let id: [u8; 32] = Readable::read(r)?;
114 let is_offer_party: bool = Readable::read(r)?;
115 let contract_info = read_vec(r)?;
116 let offer_params = ddk_messages::ser_impls::party_params::read(r)?;
117 let total_collateral: Amount = Readable::read(r)?;
118 let funding_inputs = read_vec(r)?;
119 let fund_output_serial_id: u64 = Readable::read(r)?;
120 let fee_rate_per_vb: u64 = Readable::read(r)?;
121 let cet_locktime: u32 = Readable::read(r)?;
122 let refund_locktime: u32 = Readable::read(r)?;
123
124 let mut peek = [0u8; 1];
129 r.read_exact(&mut peek)?;
130 let (contract_flags, counter_party) = if peek[0] == 0x02 || peek[0] == 0x03 {
131 let mut pubkey_bytes = [0u8; 33];
133 pubkey_bytes[0] = peek[0];
134 r.read_exact(&mut pubkey_bytes[1..])?;
135 let pk = secp256k1_zkp::PublicKey::from_slice(&pubkey_bytes)
136 .map_err(|_| DecodeError::InvalidValue)?;
137 (0u8, pk)
138 } else {
139 let counter_party: secp256k1_zkp::PublicKey = Readable::read(r)?;
141 (peek[0], counter_party)
142 };
143
144 let keys_id: KeysId = Readable::read(r)?;
145
146 Ok(Self {
147 id,
148 is_offer_party,
149 contract_info,
150 offer_params,
151 total_collateral,
152 funding_inputs,
153 fund_output_serial_id,
154 fee_rate_per_vb,
155 cet_locktime,
156 refund_locktime,
157 contract_flags,
158 counter_party,
159 keys_id,
160 })
161 }
162}
163impl_dlc_writeable_external!(RangeInfo, range_info, { (cet_index, usize), (adaptor_index, usize)});
164impl_dlc_writeable_enum!(AdaptorInfo,;; (0, Numerical, write_multi_oracle_trie, read_multi_oracle_trie), (1, NumericalWithDifference, write_multi_oracle_trie_with_diff, read_multi_oracle_trie_with_diff); (2, Enum));
165impl_dlc_writeable_external!(
166 DlcTransactions, dlc_transactions,
167 { (fund, writeable),
168 (cets, vec),
169 (refund, writeable),
170 (funding_script_pubkey, writeable),
171 (pending_close_txs, vec)}
172);
173impl_dlc_writeable!(AcceptedContract, {
174 (offered_contract, writeable),
175 (accept_params, { cb_writeable, ddk_messages::ser_impls::party_params::write, ddk_messages::ser_impls::party_params::read }),
176 (funding_inputs, vec),
177 (adaptor_infos, vec),
178 (adaptor_signatures, { cb_writeable, write_ecdsa_adaptor_signatures, read_ecdsa_adaptor_signatures }),
179 (accept_refund_signature, writeable),
180 (dlc_transactions, {cb_writeable, dlc_transactions::write, dlc_transactions::read })
181});
182impl_dlc_writeable!(SignedContract, {
183 (accepted_contract, writeable),
184 (adaptor_signatures, { cb_writeable, write_ecdsa_adaptor_signatures, read_ecdsa_adaptor_signatures }),
185 (offer_refund_signature, writeable),
186 (funding_signatures, writeable),
187 (channel_id, option)
188});
189impl_dlc_writeable!(PreClosedContract, {
190 (signed_contract, writeable),
191 (attestations, {option_cb, write_vec, read_vec}),
192 (signed_cet, writeable)
193});
194impl_dlc_writeable!(ClosedContract, {
195 (attestations, {option_cb, write_vec, read_vec}),
196 (signed_cet, writeable),
197 (contract_id, writeable),
198 (temporary_contract_id, writeable),
199 (counter_party_id, writeable),
200 (funding_txid, writeable),
201 (pnl, SignedAmount),
202 (signed_contract, writeable)
203});
204impl_dlc_writeable!(FailedAcceptContract, {(offered_contract, writeable), (accept_message, writeable), (error_message, string)});
205impl_dlc_writeable!(FailedSignContract, {(accepted_contract, writeable), (sign_message, writeable), (error_message, string)});
206
207impl_dlc_writeable_external!(DigitTrieDump<Vec<RangeInfo> >, digit_trie_dump_vec_range, { (node_data, {vec_cb, write_digit_node_data_vec_range, read_digit_node_data_vec_range}), (root, {option_cb, write_usize, read_usize}), (base, usize)});
208impl_dlc_writeable_external!(DigitTrieDump<RangeInfo>, digit_trie_dump_range, { (node_data, {vec_cb, write_digit_node_data_range, read_digit_node_data_range}), (root, {option_cb, write_usize, read_usize}), (base, usize)});
209impl_dlc_writeable_external!(DigitTrieDump<Vec<TrieNodeInfo> >, digit_trie_dump_trie, { (node_data, {vec_cb, write_digit_node_data_trie, read_digit_node_data_trie}), (root, {option_cb, write_usize, read_usize}), (base, usize)});
210impl_dlc_writeable_external!(MultiOracleTrieDump, multi_oracle_trie_dump, { (digit_trie_dump, {cb_writeable, digit_trie_dump_vec_range::write, digit_trie_dump_vec_range::read}), (threshold, usize), (oracle_numeric_infos, {cb_writeable, oracle_params::write, oracle_params::read}), (extra_cover_trie_dump, {option_cb, multi_trie_dump::write, multi_trie_dump::read}) });
211impl_dlc_writeable_external!(OracleNumericInfo, oracle_params, { (base, usize), (nb_digits, {vec_cb, write_usize, read_usize}) });
212impl_dlc_writeable_external_enum!(
213 MultiTrieNodeData<RangeInfo>,
214 multi_trie_node_data,
215 (0, Leaf, digit_trie_dump_range),
216 (1, Node, digit_trie_dump_trie)
217);
218impl_dlc_writeable_external!(MultiTrieDump<RangeInfo>, multi_trie_dump, { (node_data, {vec_cb, multi_trie_node_data::write, multi_trie_node_data::read}), (nb_tries, usize), (nb_required, usize), (min_support_exp, usize), (max_error_exp, usize), (maximize_coverage, writeable), (oracle_numeric_infos, {cb_writeable, oracle_params::write, oracle_params::read}) });
219impl_dlc_writeable_external!(MultiOracleTrieWithDiffDump, multi_oracle_trie_with_diff_dump, { (multi_trie_dump, {cb_writeable, multi_trie_dump::write, multi_trie_dump::read}), (oracle_numeric_infos, {cb_writeable, oracle_params::write, oracle_params::read}) });
220impl_dlc_writeable_external!(TrieNodeInfo, trie_node_info, { (trie_index, usize), (store_index, usize) });
221
222fn write_digit_node_data_trie<W: Writer>(
223 input: &DigitNodeData<Vec<TrieNodeInfo>>,
224 writer: &mut W,
225) -> Result<(), lightning::io::Error> {
226 let cb = |x: &Vec<TrieNodeInfo>, writer: &mut W| -> Result<(), lightning::io::Error> {
227 write_vec_cb(x, writer, &trie_node_info::write)
228 };
229 write_digit_node_data(input, writer, &cb)
230}
231
232fn read_digit_node_data_trie<R: Read>(
233 reader: &mut R,
234) -> Result<DigitNodeData<Vec<TrieNodeInfo>>, DecodeError> {
235 let cb = |reader: &mut R| -> Result<Vec<TrieNodeInfo>, DecodeError> {
236 read_vec_cb(reader, &trie_node_info::read)
237 };
238 read_digit_node_data(reader, &cb)
239}
240
241fn write_digit_node_data_range<W: Writer>(
242 input: &DigitNodeData<RangeInfo>,
243 writer: &mut W,
244) -> Result<(), lightning::io::Error> {
245 write_digit_node_data(input, writer, &range_info::write)
246}
247
248fn read_digit_node_data_range<R: Read>(
249 reader: &mut R,
250) -> Result<DigitNodeData<RangeInfo>, DecodeError> {
251 read_digit_node_data(reader, &range_info::read)
252}
253
254fn write_digit_node_data_vec_range<W: Writer>(
255 input: &DigitNodeData<Vec<RangeInfo>>,
256 writer: &mut W,
257) -> Result<(), lightning::io::Error> {
258 let cb = |x: &Vec<RangeInfo>, writer: &mut W| -> Result<(), lightning::io::Error> {
259 write_vec_cb(x, writer, &range_info::write)
260 };
261 write_digit_node_data(input, writer, &cb)
262}
263
264fn read_digit_node_data_vec_range<R: Read>(
265 reader: &mut R,
266) -> Result<DigitNodeData<Vec<RangeInfo>>, DecodeError> {
267 let cb = |reader: &mut R| -> Result<Vec<RangeInfo>, DecodeError> {
268 read_vec_cb(reader, &range_info::read)
269 };
270 read_digit_node_data(reader, &cb)
271}
272
273fn write_digit_node_data<W: Writer, T, F>(
274 input: &DigitNodeData<T>,
275 writer: &mut W,
276 cb: &F,
277) -> Result<(), lightning::io::Error>
278where
279 F: Fn(&T, &mut W) -> Result<(), lightning::io::Error>,
280{
281 write_option_cb(&input.data, writer, &cb)?;
282 write_vec_cb(&input.prefix, writer, &write_usize)?;
283 let cb = |x: &Vec<Option<usize>>, writer: &mut W| -> Result<(), lightning::io::Error> {
284 let cb = |y: &Option<usize>, writer: &mut W| -> Result<(), lightning::io::Error> {
285 write_option_cb(y, writer, &write_usize)
286 };
287 write_vec_cb(x, writer, &cb)
288 };
289 write_option_cb(&input.children, writer, &cb)
290}
291
292fn read_digit_node_data<R: Read, T, F>(
293 reader: &mut R,
294 cb: &F,
295) -> Result<DigitNodeData<T>, DecodeError>
296where
297 F: Fn(&mut R) -> Result<T, DecodeError>,
298{
299 let cb1 = |reader: &mut R| -> Result<T, DecodeError> { cb(reader) };
300 let cb = |reader: &mut R| -> Result<Vec<Option<usize>>, DecodeError> {
301 let cb = |reader: &mut R| -> Result<Option<usize>, DecodeError> {
302 read_option_cb(reader, &read_usize)
303 };
304 read_vec_cb(reader, &cb)
305 };
306
307 Ok(DigitNodeData {
308 data: read_option_cb(reader, &cb1)?,
309 prefix: read_vec_cb(reader, &read_usize)?,
310 children: read_option_cb(reader, &cb)?,
311 })
312}
313
314fn write_multi_oracle_trie<W: Writer>(
315 trie: &MultiOracleTrie,
316 w: &mut W,
317) -> Result<(), lightning::io::Error> {
318 multi_oracle_trie_dump::write(&trie.dump(), w)
319}
320
321fn read_multi_oracle_trie<R: Read>(reader: &mut R) -> Result<MultiOracleTrie, DecodeError> {
322 let dump = multi_oracle_trie_dump::read(reader)?;
323 Ok(MultiOracleTrie::from_dump(dump))
324}
325
326fn write_multi_oracle_trie_with_diff<W: Writer>(
327 trie: &MultiOracleTrieWithDiff,
328 w: &mut W,
329) -> Result<(), lightning::io::Error> {
330 multi_oracle_trie_with_diff_dump::write(&trie.dump(), w)
331}
332
333fn read_multi_oracle_trie_with_diff<R: Read>(
334 reader: &mut R,
335) -> Result<MultiOracleTrieWithDiff, DecodeError> {
336 let dump = multi_oracle_trie_with_diff_dump::read(reader)?;
337 Ok(MultiOracleTrieWithDiff::from_dump(dump))
338}