078f0f6388ff7d2b6c2eda82b1a9cc55761060d9
[rust-lightning] / lightning / src / ln / package.rs
1 // This file is Copyright its original authors, visible in version control
2 // history.
3 //
4 // This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
5 // or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
7 // You may not use this file except in accordance with one or both of these
8 // licenses.
9
10 //! Various utilities to assemble claimable outpoints in package of one or more transactions. Those
11 //! packages are attached metadata, guiding their aggregable or fee-bumping re-schedule. This file
12 //! also includes witness weight computation and fee computation methods.
13
14 use bitcoin::blockdata::constants::WITNESS_SCALE_FACTOR;
15 use bitcoin::blockdata::transaction::{TxOut,TxIn, Transaction, SigHashType};
16 use bitcoin::blockdata::transaction::OutPoint as BitcoinOutPoint;
17 use bitcoin::blockdata::script::Script;
18
19 use bitcoin::hash_types::Txid;
20
21 use bitcoin::secp256k1::key::{SecretKey,PublicKey};
22
23 use ln::PaymentPreimage;
24 use ln::chan_utils::{TxCreationKeys, HTLCOutputInCommitment, HTLC_OUTPUT_IN_COMMITMENT_SIZE};
25 use ln::chan_utils;
26 use ln::msgs::DecodeError;
27 use ln::onchaintx::OnchainTxHandler;
28 use chain::keysinterface::Sign;
29 use util::byte_utils;
30 use util::logger::Logger;
31 use util::ser::{Readable, Writer, Writeable};
32
33 use std::cmp;
34 use std::mem;
35 use std::ops::Deref;
36
37 const MAX_ALLOC_SIZE: usize = 64*1024;
38
39
40 // number_of_witness_elements + sig_length + revocation_sig + pubkey_length + revocationpubkey + witness_script_length + witness_script
41 pub(crate) const WEIGHT_REVOKED_OFFERED_HTLC: u64 = 1 + 1 + 73 + 1 + 33 + 1 + 133;
42 // number_of_witness_elements + sig_length + revocation_sig + pubkey_length + revocationpubkey + witness_script_length + witness_script
43 pub(crate) const WEIGHT_REVOKED_RECEIVED_HTLC: u64 = 1 + 1 + 73 + 1 + 33 + 1 +  139;
44 // number_of_witness_elements + sig_length + counterpartyhtlc_sig  + preimage_length + preimage + witness_script_length + witness_script
45 pub(crate) const WEIGHT_OFFERED_HTLC: u64 = 1 + 1 + 73 + 1 + 32 + 1 + 133;
46 // number_of_witness_elements + sig_length + revocation_sig + pubkey_length + revocationpubkey + witness_script_length + witness_script
47 pub(crate) const WEIGHT_RECEIVED_HTLC: u64 = 1 + 1 + 73 + 1 + 1 + 1 + 139;
48 // number_of_witness_elements + sig_length + revocation_sig + true_length + op_true + witness_script_length + witness_script
49 pub(crate) const WEIGHT_REVOKED_OUTPUT: u64 = 1 + 1 + 73 + 1 + 1 + 1 + 77;
50
51 /// A struct to describe a revoked output and corresponding information to generate a solving
52 /// witness spending a commitment `to_local` output or a second-stage HTLC transaction output.
53 ///
54 /// CSV and pubkeys are used as part of a witnessScript redeeming a balance output, amount is used
55 /// as part of the signature hash and revocation secret to generate a satisfying witness.
56 #[derive(Clone, PartialEq)]
57 pub(crate) struct RevokedOutput {
58         per_commitment_point: PublicKey,
59         counterparty_delayed_payment_base_key: PublicKey,
60         counterparty_htlc_base_key: PublicKey,
61         per_commitment_key: SecretKey,
62         weight: u64,
63         amount: u64,
64         on_counterparty_tx_csv: u16,
65 }
66
67 impl RevokedOutput {
68         pub(crate) fn build(per_commitment_point: PublicKey, counterparty_delayed_payment_base_key: PublicKey, counterparty_htlc_base_key: PublicKey, per_commitment_key: SecretKey, amount: u64, on_counterparty_tx_csv: u16) -> Self {
69                 RevokedOutput {
70                         per_commitment_point,
71                         counterparty_delayed_payment_base_key,
72                         counterparty_htlc_base_key,
73                         per_commitment_key,
74                         weight: WEIGHT_REVOKED_OUTPUT,
75                         amount,
76                         on_counterparty_tx_csv
77                 }
78         }
79 }
80
81 impl_writeable!(RevokedOutput, 33*3 + 32 + 8 + 8 + 2, {
82         per_commitment_point,
83         counterparty_delayed_payment_base_key,
84         counterparty_htlc_base_key,
85         per_commitment_key,
86         weight,
87         amount,
88         on_counterparty_tx_csv
89 });
90
91 /// A struct to describe a revoked offered output and corresponding information to generate a
92 /// solving witness.
93 ///
94 /// HTLCOuputInCommitment (hash timelock, direction) and pubkeys are used to generate a suitable
95 /// witnessScript.
96 ///
97 /// CSV is used as part of a witnessScript redeeming a balance output, amount is used as part
98 /// of the signature hash and revocation secret to generate a satisfying witness.
99 #[derive(Clone, PartialEq)]
100 pub(crate) struct RevokedHTLCOutput {
101         per_commitment_point: PublicKey,
102         counterparty_delayed_payment_base_key: PublicKey,
103         counterparty_htlc_base_key: PublicKey,
104         per_commitment_key: SecretKey,
105         weight: u64,
106         amount: u64,
107         htlc: HTLCOutputInCommitment,
108 }
109
110 impl RevokedHTLCOutput {
111         pub(crate) fn build(per_commitment_point: PublicKey, counterparty_delayed_payment_base_key: PublicKey, counterparty_htlc_base_key: PublicKey, per_commitment_key: SecretKey, amount: u64, htlc: HTLCOutputInCommitment) -> Self {
112                 let weight = if htlc.offered { WEIGHT_REVOKED_OFFERED_HTLC } else { WEIGHT_REVOKED_RECEIVED_HTLC };
113                 RevokedHTLCOutput {
114                         per_commitment_point,
115                         counterparty_delayed_payment_base_key,
116                         counterparty_htlc_base_key,
117                         per_commitment_key,
118                         weight,
119                         amount,
120                         htlc
121                 }
122         }
123 }
124
125 impl_writeable!(RevokedHTLCOutput, 33*3 + 32 + 8 + 8 + HTLC_OUTPUT_IN_COMMITMENT_SIZE, {
126         per_commitment_point,
127         counterparty_delayed_payment_base_key,
128         counterparty_htlc_base_key,
129         per_commitment_key,
130         weight,
131         amount,
132         htlc
133 });
134
135 /// A struct to describe a HTLC output on a counterparty commitment transaction.
136 ///
137 /// HTLCOutputInCommitment (hash, timelock, directon) and pubkeys are used to generate a suitable
138 /// witnessScript.
139 ///
140 /// The preimage is used as part of the witness.
141 #[derive(Clone, PartialEq)]
142 pub(crate) struct CounterpartyOfferedHTLCOutput {
143         per_commitment_point: PublicKey,
144         counterparty_delayed_payment_base_key: PublicKey,
145         counterparty_htlc_base_key: PublicKey,
146         preimage: PaymentPreimage,
147         htlc: HTLCOutputInCommitment
148 }
149
150 impl CounterpartyOfferedHTLCOutput {
151         pub(crate) fn build(per_commitment_point: PublicKey, counterparty_delayed_payment_base_key: PublicKey, counterparty_htlc_base_key: PublicKey, preimage: PaymentPreimage, htlc: HTLCOutputInCommitment) -> Self {
152                 CounterpartyOfferedHTLCOutput {
153                         per_commitment_point,
154                         counterparty_delayed_payment_base_key,
155                         counterparty_htlc_base_key,
156                         preimage,
157                         htlc
158                 }
159         }
160 }
161
162 impl_writeable!(CounterpartyOfferedHTLCOutput, 33*3 + 32 + HTLC_OUTPUT_IN_COMMITMENT_SIZE, {
163         per_commitment_point,
164         counterparty_delayed_payment_base_key,
165         counterparty_htlc_base_key,
166         preimage,
167         htlc
168 });
169
170 /// A struct to describe a HTLC output on a counterparty commitment transaction.
171 ///
172 /// HTLCOutputInCommitment (hash, timelock, directon) and pubkeys are used to generate a suitable
173 /// witnessScript.
174 #[derive(Clone, PartialEq)]
175 pub(crate) struct CounterpartyReceivedHTLCOutput {
176         per_commitment_point: PublicKey,
177         counterparty_delayed_payment_base_key: PublicKey,
178         counterparty_htlc_base_key: PublicKey,
179         htlc: HTLCOutputInCommitment
180 }
181
182 impl CounterpartyReceivedHTLCOutput {
183         pub(crate) fn build(per_commitment_point: PublicKey, counterparty_delayed_payment_base_key: PublicKey, counterparty_htlc_base_key: PublicKey, htlc: HTLCOutputInCommitment) -> Self {
184                 CounterpartyReceivedHTLCOutput {
185                         per_commitment_point,
186                         counterparty_delayed_payment_base_key,
187                         counterparty_htlc_base_key,
188                         htlc
189                 }
190         }
191 }
192
193 impl_writeable!(CounterpartyReceivedHTLCOutput, 33*3 + HTLC_OUTPUT_IN_COMMITMENT_SIZE, {
194         per_commitment_point,
195         counterparty_delayed_payment_base_key,
196         counterparty_htlc_base_key,
197         htlc
198 });
199
200 /// A struct to describe a HTLC output on holder commitment transaction.
201 ///
202 /// Either offered or received, the amount is always used as part of the bip143 sighash.
203 /// Preimage is only included as part of the witness in former case.
204 #[derive(Clone, PartialEq)]
205 pub(crate) struct HolderHTLCOutput {
206         preimage: Option<PaymentPreimage>,
207         amount: u64,
208 }
209
210 impl HolderHTLCOutput {
211         pub(crate) fn build(preimage: Option<PaymentPreimage>, amount: u64) -> Self {
212                 HolderHTLCOutput {
213                         preimage,
214                         amount
215                 }
216         }
217 }
218
219 impl_writeable!(HolderHTLCOutput, 0, {
220         preimage,
221         amount
222 });
223
224 /// A struct to describe the channel output on the funding transaction.
225 ///
226 /// witnessScript is used as part of the witness redeeming the funding utxo.
227 #[derive(Clone, PartialEq)]
228 pub(crate) struct HolderFundingOutput {
229         funding_redeemscript: Script,
230 }
231
232 impl HolderFundingOutput {
233         pub(crate) fn build(funding_redeemscript: Script) -> Self {
234                 HolderFundingOutput {
235                         funding_redeemscript,
236                 }
237         }
238 }
239
240 impl_writeable!(HolderFundingOutput, 0, {
241         funding_redeemscript
242 });
243
244 /// A wrapper encapsulating all in-protocol differing outputs types.
245 ///
246 /// The generic API offers access to an outputs common attributes or allow transformation such as
247 /// finalizing an input claiming the output.
248 #[derive(Clone, PartialEq)]
249 pub(crate) enum PackageSolvingData {
250         RevokedOutput(RevokedOutput),
251         RevokedHTLCOutput(RevokedHTLCOutput),
252         CounterpartyOfferedHTLCOutput(CounterpartyOfferedHTLCOutput),
253         CounterpartyReceivedHTLCOutput(CounterpartyReceivedHTLCOutput),
254         HolderHTLCOutput(HolderHTLCOutput),
255         HolderFundingOutput(HolderFundingOutput),
256 }
257
258 impl PackageSolvingData {
259         fn amount(&self) -> u64 {
260                 let amt = match self {
261                         PackageSolvingData::RevokedOutput(ref outp) => { outp.amount },
262                         PackageSolvingData::RevokedHTLCOutput(ref outp) => { outp.amount },
263                         PackageSolvingData::CounterpartyOfferedHTLCOutput(ref outp) => { outp.htlc.amount_msat / 1000 },
264                         PackageSolvingData::CounterpartyReceivedHTLCOutput(ref outp) => { outp.htlc.amount_msat / 1000 },
265                         // Note: Currently, amounts of holder outputs spending witnesses aren't used
266                         // as we can't malleate spending package to increase their feerate. This
267                         // should change with the remaining anchor output patchset.
268                         PackageSolvingData::HolderHTLCOutput(..) => { 0 },
269                         PackageSolvingData::HolderFundingOutput(..) => { 0 },
270                 };
271                 amt
272         }
273         fn weight(&self) -> usize {
274                 let weight = match self {
275                         PackageSolvingData::RevokedOutput(ref outp) => { outp.weight as usize },
276                         PackageSolvingData::RevokedHTLCOutput(ref outp) => { outp.weight as usize },
277                         PackageSolvingData::CounterpartyOfferedHTLCOutput(..) => { WEIGHT_OFFERED_HTLC as usize },
278                         PackageSolvingData::CounterpartyReceivedHTLCOutput(..) => { WEIGHT_RECEIVED_HTLC as usize },
279                         // Note: Currently, weights of holder outputs spending witnesses aren't used
280                         // as we can't malleate spending package to increase their feerate. This
281                         // should change with the remaining anchor output patchset.
282                         PackageSolvingData::HolderHTLCOutput(..) => { debug_assert!(false); 0 },
283                         PackageSolvingData::HolderFundingOutput(..) => { debug_assert!(false); 0 },
284                 };
285                 weight
286         }
287         fn is_compatible(&self, input: &PackageSolvingData) -> bool {
288                 match self {
289                         PackageSolvingData::RevokedOutput(..) => {
290                                 match input {
291                                         PackageSolvingData::RevokedHTLCOutput(..) => { true },
292                                         PackageSolvingData::RevokedOutput(..) => { true },
293                                         _ => { false }
294                                 }
295                         },
296                         PackageSolvingData::RevokedHTLCOutput(..) => {
297                                 match input {
298                                         PackageSolvingData::RevokedOutput(..) => { true },
299                                         PackageSolvingData::RevokedHTLCOutput(..) => { true },
300                                         _ => { false }
301                                 }
302                         },
303                         _ => { mem::discriminant(self) == mem::discriminant(&input) }
304                 }
305         }
306         fn finalize_input<Signer: Sign>(&self, bumped_tx: &mut Transaction, i: usize, onchain_handler: &mut OnchainTxHandler<Signer>) -> bool {
307                 match self {
308                         PackageSolvingData::RevokedOutput(ref outp) => {
309                                 if let Ok(chan_keys) = TxCreationKeys::derive_new(&onchain_handler.secp_ctx, &outp.per_commitment_point, &outp.counterparty_delayed_payment_base_key, &outp.counterparty_htlc_base_key, &onchain_handler.signer.pubkeys().revocation_basepoint, &onchain_handler.signer.pubkeys().htlc_basepoint) {
310                                         let witness_script = chan_utils::get_revokeable_redeemscript(&chan_keys.revocation_key, outp.on_counterparty_tx_csv, &chan_keys.broadcaster_delayed_payment_key);
311                                         //TODO: should we panic on signer failure ?
312                                         if let Ok(sig) = onchain_handler.signer.sign_justice_revoked_output(&bumped_tx, i, outp.amount, &outp.per_commitment_key, &onchain_handler.secp_ctx) {
313                                                 bumped_tx.input[i].witness.push(sig.serialize_der().to_vec());
314                                                 bumped_tx.input[i].witness[0].push(SigHashType::All as u8);
315                                                 bumped_tx.input[i].witness.push(vec!(1));
316                                                 bumped_tx.input[i].witness.push(witness_script.clone().into_bytes());
317                                         } else { return false; }
318                                 }
319                         },
320                         PackageSolvingData::RevokedHTLCOutput(ref outp) => {
321                                 if let Ok(chan_keys) = TxCreationKeys::derive_new(&onchain_handler.secp_ctx, &outp.per_commitment_point, &outp.counterparty_delayed_payment_base_key, &outp.counterparty_htlc_base_key, &onchain_handler.signer.pubkeys().revocation_basepoint, &onchain_handler.signer.pubkeys().htlc_basepoint) {
322                                         let witness_script = chan_utils::get_htlc_redeemscript_with_explicit_keys(&outp.htlc, &chan_keys.broadcaster_htlc_key, &chan_keys.countersignatory_htlc_key, &chan_keys.revocation_key);
323                                         //TODO: should we panic on signer failure ?
324                                         if let Ok(sig) = onchain_handler.signer.sign_justice_revoked_htlc(&bumped_tx, i, outp.amount, &outp.per_commitment_key, &outp.htlc, &onchain_handler.secp_ctx) {
325                                                 bumped_tx.input[i].witness.push(sig.serialize_der().to_vec());
326                                                 bumped_tx.input[i].witness[0].push(SigHashType::All as u8);
327                                                 bumped_tx.input[i].witness.push(chan_keys.revocation_key.clone().serialize().to_vec());
328                                                 bumped_tx.input[i].witness.push(witness_script.clone().into_bytes());
329                                         } else { return false; }
330                                 }
331                         },
332                         PackageSolvingData::CounterpartyOfferedHTLCOutput(ref outp) => {
333                                 if let Ok(chan_keys) = TxCreationKeys::derive_new(&onchain_handler.secp_ctx, &outp.per_commitment_point, &outp.counterparty_delayed_payment_base_key, &outp.counterparty_htlc_base_key, &onchain_handler.signer.pubkeys().revocation_basepoint, &onchain_handler.signer.pubkeys().htlc_basepoint) {
334                                         let witness_script = chan_utils::get_htlc_redeemscript_with_explicit_keys(&outp.htlc, &chan_keys.broadcaster_htlc_key, &chan_keys.countersignatory_htlc_key, &chan_keys.revocation_key);
335
336                                         if let Ok(sig) = onchain_handler.signer.sign_counterparty_htlc_transaction(&bumped_tx, i, &outp.htlc.amount_msat / 1000, &outp.per_commitment_point, &outp.htlc, &onchain_handler.secp_ctx) {
337                                                 bumped_tx.input[i].witness.push(sig.serialize_der().to_vec());
338                                                 bumped_tx.input[i].witness[0].push(SigHashType::All as u8);
339                                                 bumped_tx.input[i].witness.push(outp.preimage.0.to_vec());
340                                                 bumped_tx.input[i].witness.push(witness_script.clone().into_bytes());
341                                         }
342                                 }
343                         },
344                         PackageSolvingData::CounterpartyReceivedHTLCOutput(ref outp) => {
345                                 if let Ok(chan_keys) = TxCreationKeys::derive_new(&onchain_handler.secp_ctx, &outp.per_commitment_point, &outp.counterparty_delayed_payment_base_key, &outp.counterparty_htlc_base_key, &onchain_handler.signer.pubkeys().revocation_basepoint, &onchain_handler.signer.pubkeys().htlc_basepoint) {
346                                         let witness_script = chan_utils::get_htlc_redeemscript_with_explicit_keys(&outp.htlc, &chan_keys.broadcaster_htlc_key, &chan_keys.countersignatory_htlc_key, &chan_keys.revocation_key);
347
348                                         bumped_tx.lock_time = outp.htlc.cltv_expiry; // Right now we don't aggregate time-locked transaction, if we do we should set lock_time before to avoid breaking hash computation
349                                         if let Ok(sig) = onchain_handler.signer.sign_counterparty_htlc_transaction(&bumped_tx, i, &outp.htlc.amount_msat / 1000, &outp.per_commitment_point, &outp.htlc, &onchain_handler.secp_ctx) {
350                                                 bumped_tx.input[i].witness.push(sig.serialize_der().to_vec());
351                                                 bumped_tx.input[i].witness[0].push(SigHashType::All as u8);
352                                                 // Due to BIP146 (MINIMALIF) this must be a zero-length element to relay.
353                                                 bumped_tx.input[i].witness.push(vec![]);
354                                                 bumped_tx.input[i].witness.push(witness_script.clone().into_bytes());
355                                         }
356                                 }
357                         },
358                         _ => { panic!("API Error!"); }
359                 }
360                 true
361         }
362         fn get_finalized_tx<Signer: Sign>(&self, outpoint: &BitcoinOutPoint, onchain_handler: &mut OnchainTxHandler<Signer>) -> Option<Transaction> {
363                 match self {
364                         PackageSolvingData::HolderHTLCOutput(ref outp) => { return onchain_handler.get_fully_signed_htlc_tx(outpoint, &outp.preimage); }
365                         PackageSolvingData::HolderFundingOutput(ref outp) => { return Some(onchain_handler.get_fully_signed_holder_tx(&outp.funding_redeemscript)); }
366                         _ => { panic!("API Error!"); }
367                 }
368         }
369 }
370
371 impl Writeable for PackageSolvingData {
372         fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ::std::io::Error> {
373                 match self {
374                         PackageSolvingData::RevokedOutput(ref revoked_outp) => {
375                                 0u8.write(writer)?;
376                                 revoked_outp.write(writer)?;
377                         },
378                         PackageSolvingData::RevokedHTLCOutput(ref revoked_outp) => {
379                                 1u8.write(writer)?;
380                                 revoked_outp.write(writer)?;
381                         },
382                         PackageSolvingData::CounterpartyOfferedHTLCOutput(ref counterparty_outp) => {
383                                 2u8.write(writer)?;
384                                 counterparty_outp.write(writer)?;
385                         },
386                         PackageSolvingData::CounterpartyReceivedHTLCOutput(ref counterparty_outp) => {
387                                 3u8.write(writer)?;
388                                 counterparty_outp.write(writer)?;
389                         },
390                         PackageSolvingData::HolderHTLCOutput(ref holder_outp) => {
391                                 4u8.write(writer)?;
392                                 holder_outp.write(writer)?;
393                         },
394                         PackageSolvingData::HolderFundingOutput(ref funding_outp) => {
395                                 5u8.write(writer)?;
396                                 funding_outp.write(writer)?;
397                         }
398                 }
399                 Ok(())
400         }
401 }
402
403 impl Readable for PackageSolvingData {
404         fn read<R: ::std::io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
405                 let byte = <u8 as Readable>::read(reader)?;
406                 let solving_data = match byte {
407                         0 => {
408                                 PackageSolvingData::RevokedOutput(Readable::read(reader)?)
409                         },
410                         1 => {
411                                 PackageSolvingData::RevokedHTLCOutput(Readable::read(reader)?)
412                         },
413                         2 => {
414                                 PackageSolvingData::CounterpartyOfferedHTLCOutput(Readable::read(reader)?)
415                         },
416                         3 => {
417                                 PackageSolvingData::CounterpartyReceivedHTLCOutput(Readable::read(reader)?)
418                         },
419                         4 => {
420                                 PackageSolvingData::HolderHTLCOutput(Readable::read(reader)?)
421                         },
422                         5 => {
423                                 PackageSolvingData::HolderFundingOutput(Readable::read(reader)?)
424                         }
425                         _ => return Err(DecodeError::UnknownVersion)
426                 };
427                 Ok(solving_data)
428         }
429 }
430
431 /// A malleable package might be aggregated with other packages to save on fees.
432 /// A untractable package has been counter-signed and aggregable will break cached counterparty
433 /// signatures.
434 #[derive(Clone, PartialEq)]
435 pub(crate) enum PackageMalleability {
436         Malleable,
437         Untractable,
438 }
439
440 /// A structure to describe a package content that is generated by ChannelMonitor and
441 /// used by OnchainTxHandler to generate and broadcast transactions settling onchain claims.
442 ///
443 /// A package is defined as one or more transactions claiming onchain outputs in reaction
444 /// to confirmation of a channel transaction. Those packages might be aggregated to save on
445 /// fees, if satisfaction of outputs's witnessScript let's us do so.
446 ///
447 /// As packages are time-sensitive, we fee-bump and rebroadcast them at scheduled intervals.
448 /// Failing to confirm a package translate as a loss of funds for the user.
449 #[derive(Clone, PartialEq)]
450 pub struct PackageTemplate {
451         // List of onchain outputs and solving data to generate satisfying witnesses.
452         inputs: Vec<(BitcoinOutPoint, PackageSolvingData)>,
453         // Packages are deemed as malleable if we have local knwoledge of at least one set of
454         // private keys yielding a satisfying witnesses. Malleability implies that we can aggregate
455         // packages among them to save on fees or rely on RBF to bump their feerates.
456         // Untractable packages have been counter-signed and thus imply that we can't aggregate
457         // them without breaking signatures. Fee-bumping strategy will also rely on CPFP.
458         malleability: PackageMalleability,
459         // Block height after which the earlier-output belonging to this package is mature for a
460         // competing claim by the counterparty. As our chain tip becomes nearer from the timelock,
461         // the fee-bumping frequency will increase. See `OnchainTxHandler::get_height_timer`.
462         soonest_conf_deadline: u32,
463         // Determines if this package can be aggregated.
464         // Timelocked outputs belonging to the same transaction might have differing
465         // satisfying heights. Picking up the later height among the output set would be a valid
466         // aggregable strategy but it comes with at least 2 trade-offs :
467         // * earlier-output fund are going to take longer to come back
468         // * CLTV delta backing up a corresponding HTLC on an upstream channel could be swallowed
469         // by the requirement of the later-output part of the set
470         // For now, we mark such timelocked outputs as non-aggregable, though we might introduce
471         // smarter aggregable strategy in the future.
472         aggregable: bool,
473         // Cache of package feerate committed at previous (re)broadcast. If bumping resources
474         // (either claimed output value or external utxo), it will keep increasing until holder
475         // or counterparty successful claim.
476         feerate_previous: u64,
477         // Cache of next height at which fee-bumping and rebroadcast will be attempted. In
478         // the future, we might abstract it to an observed mempool fluctuation.
479         height_timer: Option<u32>,
480         // Confirmation height of the claimed outputs set transaction. In case of reorg reaching
481         // it, we wipe out and forget the package.
482         height_original: u32,
483 }
484
485 impl PackageTemplate {
486         pub(crate) fn is_malleable(&self) -> bool {
487                 self.malleability == PackageMalleability::Malleable
488         }
489         pub(crate) fn timelock(&self) -> u32 {
490                 self.soonest_conf_deadline
491         }
492         pub(crate) fn aggregable(&self) -> bool {
493                 self.aggregable
494         }
495         pub(crate) fn feerate(&self) -> u64 {
496                 self.feerate_previous
497         }
498         pub(crate) fn set_feerate(&mut self, new_feerate: u64) {
499                 self.feerate_previous = new_feerate;
500         }
501         pub(crate) fn timer(&self) -> Option<u32> {
502                 if let Some(ref timer) = self.height_timer {
503                         return Some(*timer);
504                 }
505                 None
506         }
507         pub(crate) fn set_timer(&mut self, new_timer: Option<u32>) {
508                 self.height_timer = new_timer;
509         }
510         pub(crate) fn outpoints(&self) -> Vec<&BitcoinOutPoint> {
511                 self.inputs.iter().map(|(o, _)| o).collect()
512         }
513         pub(crate) fn split_package(&mut self, split_outp: &BitcoinOutPoint) -> Option<PackageTemplate> {
514                 match self.malleability {
515                         PackageMalleability::Malleable => {
516                                 let mut split_package = None;
517                                 let timelock = self.soonest_conf_deadline;
518                                 let aggregable = self.aggregable;
519                                 let feerate_previous = self.feerate_previous;
520                                 let height_timer = self.height_timer;
521                                 let height_original = self.height_original;
522                                 self.inputs.retain(|outp| {
523                                         if *split_outp == outp.0 {
524                                                 split_package = Some(PackageTemplate {
525                                                         inputs: vec![(outp.0, outp.1.clone())],
526                                                         malleability: PackageMalleability::Malleable,
527                                                         soonest_conf_deadline: timelock,
528                                                         aggregable,
529                                                         feerate_previous,
530                                                         height_timer,
531                                                         height_original,
532                                                 });
533                                                 return false;
534                                         }
535                                         return true;
536                                 });
537                                 return split_package;
538                         },
539                         _ => {
540                                 // Note, we may try to split on remote transaction for
541                                 // which we don't have a competing one (HTLC-Success before
542                                 // timelock expiration). This explain we don't panic!
543                                 // We should refactor OnchainTxHandler::block_connected to
544                                 // only test equality on competing claims.
545                                 return None;
546                         }
547                 }
548         }
549         pub(crate) fn merge_package(&mut self, mut merge_from: PackageTemplate) {
550                 assert_eq!(self.height_original, merge_from.height_original);
551                 if self.malleability == PackageMalleability::Untractable || merge_from.malleability == PackageMalleability::Untractable {
552                         panic!("Merging template on untractable packages");
553                 }
554                 if !self.aggregable || !merge_from.aggregable {
555                         panic!("Merging non aggregatable packages");
556                 }
557                 if let Some((_, lead_input)) = self.inputs.first() {
558                         for (_, v) in merge_from.inputs.iter() {
559                                 if !lead_input.is_compatible(v) { panic!("Merging outputs from differing types !"); }
560                         }
561                 } else { panic!("Merging template on an empty package"); }
562                 for (k, v) in merge_from.inputs.drain(..) {
563                         self.inputs.push((k, v));
564                 }
565                 //TODO: verify coverage and sanity?
566                 if self.soonest_conf_deadline > merge_from.soonest_conf_deadline {
567                         self.soonest_conf_deadline = merge_from.soonest_conf_deadline;
568                 }
569                 if self.feerate_previous > merge_from.feerate_previous {
570                         self.feerate_previous = merge_from.feerate_previous;
571                 }
572                 self.height_timer = cmp::min(self.height_timer, merge_from.height_timer);
573         }
574         pub(crate) fn package_amount(&self) -> u64 {
575                 let mut amounts = 0;
576                 for (_, outp) in self.inputs.iter() {
577                         amounts += outp.amount();
578                 }
579                 amounts
580         }
581         pub(crate) fn package_weight(&self, destination_script: &Script) -> usize {
582                 let mut inputs_weight = 0;
583                 let mut witnesses_weight = 2; // count segwit flags
584                 for (_, outp) in self.inputs.iter() {
585                         // previous_out_point: 36 bytes ; var_int: 1 byte ; sequence: 4 bytes
586                         inputs_weight += 41 * WITNESS_SCALE_FACTOR;
587                         witnesses_weight += outp.weight();
588                 }
589                 // version: 4 bytes ; count_tx_in: 1 byte ; count_tx_out: 1 byte ; lock_time: 4 bytes
590                 let transaction_weight = 10 * WITNESS_SCALE_FACTOR;
591                 // value: 8 bytes ; var_int: 1 byte ; pk_script: `destination_script.len()`
592                 let output_weight = (8 + 1 + destination_script.len()) * WITNESS_SCALE_FACTOR;
593                 inputs_weight + witnesses_weight + transaction_weight + output_weight
594         }
595         pub(crate) fn finalize_package<L: Deref, Signer: Sign>(&self, onchain_handler: &mut OnchainTxHandler<Signer>, value: u64, destination_script: Script, logger: &L) -> Option<Transaction>
596                 where L::Target: Logger,
597         {
598                 match self.malleability {
599                         PackageMalleability::Malleable => {
600                                 let mut bumped_tx = Transaction {
601                                         version: 2,
602                                         lock_time: 0,
603                                         input: vec![],
604                                         output: vec![TxOut {
605                                                 script_pubkey: destination_script,
606                                                 value,
607                                         }],
608                                 };
609                                 for (outpoint, _) in self.inputs.iter() {
610                                         bumped_tx.input.push(TxIn {
611                                                 previous_output: *outpoint,
612                                                 script_sig: Script::new(),
613                                                 sequence: 0xfffffffd,
614                                                 witness: Vec::new(),
615                                         });
616                                 }
617                                 for (i, (outpoint, out)) in self.inputs.iter().enumerate() {
618                                         log_trace!(logger, "Adding claiming input for outpoint {}:{}", outpoint.txid, outpoint.vout);
619                                         if !out.finalize_input(&mut bumped_tx, i, onchain_handler) { return None; }
620                                 }
621                                 log_trace!(logger, "Finalized transaction {} ready to broadcast", bumped_tx.txid());
622                                 return Some(bumped_tx);
623                         },
624                         PackageMalleability::Untractable => {
625                                 if let Some((outpoint, outp)) = self.inputs.first() {
626                                         if let Some(final_tx) = outp.get_finalized_tx(outpoint, onchain_handler) {
627                                                 log_trace!(logger, "Adding claiming input for outpoint {}:{}", outpoint.txid, outpoint.vout);
628                                                 log_trace!(logger, "Finalized transaction {} ready to broadcast", final_tx.txid());
629                                                 return Some(final_tx);
630                                         }
631                                         return None;
632                                 } else { panic!("API Error: Package must not be inputs empty"); }
633                         },
634                 }
635         }
636         pub (crate) fn build_package(txid: Txid, vout: u32, input_solving_data: PackageSolvingData, soonest_conf_deadline: u32, aggregable: bool, height_original: u32) -> Self {
637                 let malleability = match input_solving_data {
638                         PackageSolvingData::RevokedOutput(..) => { PackageMalleability::Malleable },
639                         PackageSolvingData::RevokedHTLCOutput(..) => { PackageMalleability::Malleable },
640                         PackageSolvingData::CounterpartyOfferedHTLCOutput(..) => { PackageMalleability::Malleable },
641                         PackageSolvingData::CounterpartyReceivedHTLCOutput(..) => { PackageMalleability::Malleable },
642                         PackageSolvingData::HolderHTLCOutput(..) => { PackageMalleability::Untractable },
643                         PackageSolvingData::HolderFundingOutput(..) => { PackageMalleability::Untractable },
644                 };
645                 let mut inputs = Vec::with_capacity(1);
646                 inputs.push((BitcoinOutPoint { txid, vout }, input_solving_data));
647                 PackageTemplate {
648                         inputs,
649                         malleability,
650                         soonest_conf_deadline,
651                         aggregable,
652                         feerate_previous: 0,
653                         height_timer: None,
654                         height_original,
655                 }
656         }
657 }
658
659 impl Writeable for PackageTemplate {
660         fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ::std::io::Error> {
661                 writer.write_all(&byte_utils::be64_to_array(self.inputs.len() as u64))?;
662                 for (ref outpoint, ref rev_outp) in self.inputs.iter() {
663                         outpoint.write(writer)?;
664                         rev_outp.write(writer)?;
665                 }
666                 self.soonest_conf_deadline.write(writer)?;
667                 self.feerate_previous.write(writer)?;
668                 self.height_timer.write(writer)?;
669                 self.height_original.write(writer)?;
670                 Ok(())
671         }
672 }
673
674 impl Readable for PackageTemplate {
675         fn read<R: ::std::io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
676                 let inputs_count = <u64 as Readable>::read(reader)?;
677                 let mut inputs: Vec<(BitcoinOutPoint, PackageSolvingData)> = Vec::with_capacity(cmp::min(inputs_count as usize, MAX_ALLOC_SIZE / 128));
678                 for _ in 0..inputs_count {
679                         let outpoint = Readable::read(reader)?;
680                         let rev_outp = Readable::read(reader)?;
681                         inputs.push((outpoint, rev_outp));
682                 }
683                 let (malleability, aggregable) = if let Some((_, lead_input)) = inputs.first() {
684                         match lead_input {
685                                 PackageSolvingData::RevokedOutput(..) => { (PackageMalleability::Malleable, true) },
686                                 PackageSolvingData::RevokedHTLCOutput(..) => { (PackageMalleability::Malleable, true) },
687                                 PackageSolvingData::CounterpartyOfferedHTLCOutput(..) => { (PackageMalleability::Malleable, true) },
688                                 PackageSolvingData::CounterpartyReceivedHTLCOutput(..) => { (PackageMalleability::Malleable, false) },
689                                 PackageSolvingData::HolderHTLCOutput(..) => { (PackageMalleability::Untractable, false) },
690                                 PackageSolvingData::HolderFundingOutput(..) => { (PackageMalleability::Untractable, false) },
691                         }
692                 } else { return Err(DecodeError::InvalidValue); };
693                 let soonest_conf_deadline = Readable::read(reader)?;
694                 let feerate_previous = Readable::read(reader)?;
695                 let height_timer = Readable::read(reader)?;
696                 let height_original = Readable::read(reader)?;
697                 Ok(PackageTemplate {
698                         inputs,
699                         malleability,
700                         soonest_conf_deadline,
701                         aggregable,
702                         feerate_previous,
703                         height_timer,
704                         height_original,
705                 })
706         }
707 }
708
709 /// Utilities for computing witnesses weight and feerate computation for onchain operation
710 #[derive(PartialEq, Clone, Copy)]
711 pub(crate) enum InputDescriptors {
712         RevokedOfferedHTLC,
713         RevokedReceivedHTLC,
714         OfferedHTLC,
715         ReceivedHTLC,
716         RevokedOutput, // either a revoked to_holder output on commitment tx, a revoked HTLC-Timeout output or a revoked HTLC-Success output
717 }
718
719 impl Writeable for InputDescriptors {
720         fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ::std::io::Error> {
721                 match self {
722                         &InputDescriptors::RevokedOfferedHTLC => {
723                                 writer.write_all(&[0; 1])?;
724                         },
725                         &InputDescriptors::RevokedReceivedHTLC => {
726                                 writer.write_all(&[1; 1])?;
727                         },
728                         &InputDescriptors::OfferedHTLC => {
729                                 writer.write_all(&[2; 1])?;
730                         },
731                         &InputDescriptors::ReceivedHTLC => {
732                                 writer.write_all(&[3; 1])?;
733                         }
734                         &InputDescriptors::RevokedOutput => {
735                                 writer.write_all(&[4; 1])?;
736                         }
737                 }
738                 Ok(())
739         }
740 }
741
742 impl Readable for InputDescriptors {
743         fn read<R: ::std::io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
744                 let input_descriptor = match <u8 as Readable>::read(reader)? {
745                         0 => {
746                                 InputDescriptors::RevokedOfferedHTLC
747                         },
748                         1 => {
749                                 InputDescriptors::RevokedReceivedHTLC
750                         },
751                         2 => {
752                                 InputDescriptors::OfferedHTLC
753                         },
754                         3 => {
755                                 InputDescriptors::ReceivedHTLC
756                         },
757                         4 => {
758                                 InputDescriptors::RevokedOutput
759                         }
760                         _ => return Err(DecodeError::InvalidValue),
761                 };
762                 Ok(input_descriptor)
763         }
764 }
765
766 pub(crate) fn get_witnesses_weight(inputs: &[InputDescriptors]) -> usize {
767         let mut tx_weight = 2; // count segwit flags
768         for inp in inputs {
769                 // We use expected weight (and not actual) as signatures and time lock delays may vary
770                 tx_weight +=  match inp {
771                         // number_of_witness_elements + sig_length + revocation_sig + pubkey_length + revocationpubkey + witness_script_length + witness_script
772                         &InputDescriptors::RevokedOfferedHTLC => {
773                                 1 + 1 + 73 + 1 + 33 + 1 + 133
774                         },
775                         // number_of_witness_elements + sig_length + revocation_sig + pubkey_length + revocationpubkey + witness_script_length + witness_script
776                         &InputDescriptors::RevokedReceivedHTLC => {
777                                 1 + 1 + 73 + 1 + 33 + 1 + 139
778                         },
779                         // number_of_witness_elements + sig_length + counterpartyhtlc_sig  + preimage_length + preimage + witness_script_length + witness_script
780                         &InputDescriptors::OfferedHTLC => {
781                                 1 + 1 + 73 + 1 + 32 + 1 + 133
782                         },
783                         // number_of_witness_elements + sig_length + revocation_sig + pubkey_length + revocationpubkey + witness_script_length + witness_script
784                         &InputDescriptors::ReceivedHTLC => {
785                                 1 + 1 + 73 + 1 + 1 + 1 + 139
786                         },
787                         // number_of_witness_elements + sig_length + revocation_sig + true_length + op_true + witness_script_length + witness_script
788                         &InputDescriptors::RevokedOutput => {
789                                 1 + 1 + 73 + 1 + 1 + 1 + 77
790                         },
791                 };
792         }
793         tx_weight
794 }