60341620887b59dc3fcadd06e5d6b5d7f1f2b21b
[rust-lightning] / lightning / src / ln / interactivetxs.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 use crate::io_extras::sink;
11 use crate::prelude::*;
12 use core::ops::Deref;
13
14 use bitcoin::blockdata::constants::WITNESS_SCALE_FACTOR;
15 use bitcoin::consensus::Encodable;
16 use bitcoin::policy::MAX_STANDARD_TX_WEIGHT;
17 use bitcoin::{
18         absolute::LockTime as AbsoluteLockTime, OutPoint, ScriptBuf, Sequence, Transaction, TxIn,
19         TxOut, Weight,
20 };
21
22 use crate::chain::chaininterface::fee_for_weight;
23 use crate::events::bump_transaction::{BASE_INPUT_WEIGHT, EMPTY_SCRIPT_SIG_WEIGHT};
24 use crate::ln::channel::TOTAL_BITCOIN_SUPPLY_SATOSHIS;
25 use crate::ln::msgs;
26 use crate::ln::msgs::SerialId;
27 use crate::ln::types::ChannelId;
28 use crate::sign::{EntropySource, P2TR_KEY_PATH_WITNESS_WEIGHT, P2WPKH_WITNESS_WEIGHT};
29 use crate::util::ser::TransactionU16LenLimited;
30
31 /// The number of received `tx_add_input` messages during a negotiation at which point the
32 /// negotiation MUST be failed.
33 const MAX_RECEIVED_TX_ADD_INPUT_COUNT: u16 = 4096;
34
35 /// The number of received `tx_add_output` messages during a negotiation at which point the
36 /// negotiation MUST be failed.
37 const MAX_RECEIVED_TX_ADD_OUTPUT_COUNT: u16 = 4096;
38
39 /// The number of inputs or outputs that the state machine can have, before it MUST fail the
40 /// negotiation.
41 const MAX_INPUTS_OUTPUTS_COUNT: usize = 252;
42
43 /// The total weight of the common fields whose fee is paid by the initiator of the interactive
44 /// transaction construction protocol.
45 const TX_COMMON_FIELDS_WEIGHT: u64 = (4 /* version */ + 4 /* locktime */ + 1 /* input count */ +
46         1 /* output count */) * WITNESS_SCALE_FACTOR as u64 + 2 /* segwit marker + flag */;
47
48 // BOLT 3 - Lower bounds for input weights
49
50 /// Lower bound for P2WPKH input weight
51 pub(crate) const P2WPKH_INPUT_WEIGHT_LOWER_BOUND: u64 =
52         BASE_INPUT_WEIGHT + EMPTY_SCRIPT_SIG_WEIGHT + P2WPKH_WITNESS_WEIGHT;
53
54 /// Lower bound for P2WSH input weight is chosen as same as P2WPKH input weight in BOLT 3
55 pub(crate) const P2WSH_INPUT_WEIGHT_LOWER_BOUND: u64 = P2WPKH_INPUT_WEIGHT_LOWER_BOUND;
56
57 /// Lower bound for P2TR input weight is chosen as the key spend path.
58 /// Not specified in BOLT 3, but a reasonable lower bound.
59 pub(crate) const P2TR_INPUT_WEIGHT_LOWER_BOUND: u64 =
60         BASE_INPUT_WEIGHT + EMPTY_SCRIPT_SIG_WEIGHT + P2TR_KEY_PATH_WITNESS_WEIGHT;
61
62 /// Lower bound for unknown segwit version input weight is chosen the same as P2WPKH in BOLT 3
63 pub(crate) const UNKNOWN_SEGWIT_VERSION_INPUT_WEIGHT_LOWER_BOUND: u64 =
64         P2WPKH_INPUT_WEIGHT_LOWER_BOUND;
65
66 trait SerialIdExt {
67         fn is_for_initiator(&self) -> bool;
68         fn is_for_non_initiator(&self) -> bool;
69 }
70
71 impl SerialIdExt for SerialId {
72         fn is_for_initiator(&self) -> bool {
73                 self % 2 == 0
74         }
75
76         fn is_for_non_initiator(&self) -> bool {
77                 !self.is_for_initiator()
78         }
79 }
80
81 #[derive(Debug, Clone, PartialEq)]
82 pub(crate) enum AbortReason {
83         InvalidStateTransition,
84         UnexpectedCounterpartyMessage,
85         ReceivedTooManyTxAddInputs,
86         ReceivedTooManyTxAddOutputs,
87         IncorrectInputSequenceValue,
88         IncorrectSerialIdParity,
89         SerialIdUnknown,
90         DuplicateSerialId,
91         PrevTxOutInvalid,
92         ExceededMaximumSatsAllowed,
93         ExceededNumberOfInputsOrOutputs,
94         TransactionTooLarge,
95         BelowDustLimit,
96         InvalidOutputScript,
97         InsufficientFees,
98         OutputsValueExceedsInputsValue,
99         InvalidTx,
100 }
101
102 #[derive(Debug, Clone, PartialEq, Eq)]
103 pub(crate) struct InteractiveTxInput {
104         serial_id: SerialId,
105         input: TxIn,
106         prev_output: TxOut,
107 }
108
109 #[derive(Debug, Clone, PartialEq, Eq)]
110 pub(crate) struct InteractiveTxOutput {
111         serial_id: SerialId,
112         tx_out: TxOut,
113 }
114
115 #[derive(Debug, Clone, PartialEq, Eq)]
116 pub(crate) struct ConstructedTransaction {
117         holder_is_initiator: bool,
118
119         inputs: Vec<InteractiveTxInput>,
120         outputs: Vec<InteractiveTxOutput>,
121
122         local_inputs_value_satoshis: u64,
123         local_outputs_value_satoshis: u64,
124
125         remote_inputs_value_satoshis: u64,
126         remote_outputs_value_satoshis: u64,
127
128         lock_time: AbsoluteLockTime,
129 }
130
131 impl ConstructedTransaction {
132         fn new(context: NegotiationContext) -> Self {
133                 let local_inputs_value_satoshis = context
134                         .inputs
135                         .iter()
136                         .filter(|(serial_id, _)| {
137                                 !is_serial_id_valid_for_counterparty(context.holder_is_initiator, serial_id)
138                         })
139                         .fold(0u64, |value, (_, input)| value.saturating_add(input.prev_output.value));
140
141                 let local_outputs_value_satoshis = context
142                         .outputs
143                         .iter()
144                         .filter(|(serial_id, _)| {
145                                 !is_serial_id_valid_for_counterparty(context.holder_is_initiator, serial_id)
146                         })
147                         .fold(0u64, |value, (_, output)| value.saturating_add(output.tx_out.value));
148
149                 Self {
150                         holder_is_initiator: context.holder_is_initiator,
151
152                         local_inputs_value_satoshis,
153                         local_outputs_value_satoshis,
154
155                         remote_inputs_value_satoshis: context.remote_inputs_value(),
156                         remote_outputs_value_satoshis: context.remote_outputs_value(),
157
158                         inputs: context.inputs.into_values().collect(),
159                         outputs: context.outputs.into_values().collect(),
160
161                         lock_time: context.tx_locktime,
162                 }
163         }
164
165         pub fn weight(&self) -> Weight {
166                 let inputs_weight = self.inputs.iter().fold(
167                         Weight::from_wu(0),
168                         |weight, InteractiveTxInput { prev_output, .. }| {
169                                 weight.checked_add(estimate_input_weight(prev_output)).unwrap_or(Weight::MAX)
170                         },
171                 );
172                 let outputs_weight = self.outputs.iter().fold(
173                         Weight::from_wu(0),
174                         |weight, InteractiveTxOutput { tx_out, .. }| {
175                                 weight.checked_add(get_output_weight(&tx_out.script_pubkey)).unwrap_or(Weight::MAX)
176                         },
177                 );
178                 Weight::from_wu(TX_COMMON_FIELDS_WEIGHT)
179                         .checked_add(inputs_weight)
180                         .and_then(|weight| weight.checked_add(outputs_weight))
181                         .unwrap_or(Weight::MAX)
182         }
183
184         pub fn into_unsigned_tx(self) -> Transaction {
185                 // Inputs and outputs must be sorted by serial_id
186                 let ConstructedTransaction { mut inputs, mut outputs, .. } = self;
187
188                 inputs.sort_unstable_by_key(|InteractiveTxInput { serial_id, .. }| *serial_id);
189                 outputs.sort_unstable_by_key(|InteractiveTxOutput { serial_id, .. }| *serial_id);
190
191                 let input: Vec<TxIn> =
192                         inputs.into_iter().map(|InteractiveTxInput { input, .. }| input).collect();
193                 let output: Vec<TxOut> =
194                         outputs.into_iter().map(|InteractiveTxOutput { tx_out, .. }| tx_out).collect();
195
196                 Transaction { version: 2, lock_time: self.lock_time, input, output }
197         }
198 }
199
200 #[derive(Debug)]
201 struct NegotiationContext {
202         holder_is_initiator: bool,
203         received_tx_add_input_count: u16,
204         received_tx_add_output_count: u16,
205         inputs: HashMap<SerialId, InteractiveTxInput>,
206         prevtx_outpoints: HashSet<OutPoint>,
207         outputs: HashMap<SerialId, InteractiveTxOutput>,
208         tx_locktime: AbsoluteLockTime,
209         feerate_sat_per_kw: u32,
210 }
211
212 pub(crate) fn estimate_input_weight(prev_output: &TxOut) -> Weight {
213         Weight::from_wu(if prev_output.script_pubkey.is_v0_p2wpkh() {
214                 P2WPKH_INPUT_WEIGHT_LOWER_BOUND
215         } else if prev_output.script_pubkey.is_v0_p2wsh() {
216                 P2WSH_INPUT_WEIGHT_LOWER_BOUND
217         } else if prev_output.script_pubkey.is_v1_p2tr() {
218                 P2TR_INPUT_WEIGHT_LOWER_BOUND
219         } else {
220                 UNKNOWN_SEGWIT_VERSION_INPUT_WEIGHT_LOWER_BOUND
221         })
222 }
223
224 pub(crate) fn get_output_weight(script_pubkey: &ScriptBuf) -> Weight {
225         Weight::from_wu(
226                 (8 /* value */ + script_pubkey.consensus_encode(&mut sink()).unwrap() as u64)
227                         * WITNESS_SCALE_FACTOR as u64,
228         )
229 }
230
231 fn is_serial_id_valid_for_counterparty(holder_is_initiator: bool, serial_id: &SerialId) -> bool {
232         // A received `SerialId`'s parity must match the role of the counterparty.
233         holder_is_initiator == serial_id.is_for_non_initiator()
234 }
235
236 impl NegotiationContext {
237         fn is_serial_id_valid_for_counterparty(&self, serial_id: &SerialId) -> bool {
238                 is_serial_id_valid_for_counterparty(self.holder_is_initiator, serial_id)
239         }
240
241         fn remote_inputs_value(&self) -> u64 {
242                 self.inputs
243                         .iter()
244                         .filter(|(serial_id, _)| self.is_serial_id_valid_for_counterparty(serial_id))
245                         .fold(0u64, |acc, (_, InteractiveTxInput { prev_output, .. })| {
246                                 acc.saturating_add(prev_output.value)
247                         })
248         }
249
250         fn remote_outputs_value(&self) -> u64 {
251                 self.outputs
252                         .iter()
253                         .filter(|(serial_id, _)| self.is_serial_id_valid_for_counterparty(serial_id))
254                         .fold(0u64, |acc, (_, InteractiveTxOutput { tx_out, .. })| {
255                                 acc.saturating_add(tx_out.value)
256                         })
257         }
258
259         fn remote_inputs_weight(&self) -> Weight {
260                 Weight::from_wu(
261                         self.inputs
262                                 .iter()
263                                 .filter(|(serial_id, _)| self.is_serial_id_valid_for_counterparty(serial_id))
264                                 .fold(0u64, |weight, (_, InteractiveTxInput { prev_output, .. })| {
265                                         weight.saturating_add(estimate_input_weight(prev_output).to_wu())
266                                 }),
267                 )
268         }
269
270         fn remote_outputs_weight(&self) -> Weight {
271                 Weight::from_wu(
272                         self.outputs
273                                 .iter()
274                                 .filter(|(serial_id, _)| self.is_serial_id_valid_for_counterparty(serial_id))
275                                 .fold(0u64, |weight, (_, InteractiveTxOutput { tx_out, .. })| {
276                                         weight.saturating_add(get_output_weight(&tx_out.script_pubkey).to_wu())
277                                 }),
278                 )
279         }
280
281         fn received_tx_add_input(&mut self, msg: &msgs::TxAddInput) -> Result<(), AbortReason> {
282                 // The interactive-txs spec calls for us to fail negotiation if the `prevtx` we receive is
283                 // invalid. However, we would not need to account for this explicit negotiation failure
284                 // mode here since `PeerManager` would already disconnect the peer if the `prevtx` is
285                 // invalid; implicitly ending the negotiation.
286
287                 if !self.is_serial_id_valid_for_counterparty(&msg.serial_id) {
288                         // The receiving node:
289                         //  - MUST fail the negotiation if:
290                         //     - the `serial_id` has the wrong parity
291                         return Err(AbortReason::IncorrectSerialIdParity);
292                 }
293
294                 self.received_tx_add_input_count += 1;
295                 if self.received_tx_add_input_count > MAX_RECEIVED_TX_ADD_INPUT_COUNT {
296                         // The receiving node:
297                         //  - MUST fail the negotiation if:
298                         //     - if has received 4096 `tx_add_input` messages during this negotiation
299                         return Err(AbortReason::ReceivedTooManyTxAddInputs);
300                 }
301
302                 if msg.sequence >= 0xFFFFFFFE {
303                         // The receiving node:
304                         //  - MUST fail the negotiation if:
305                         //    - `sequence` is set to `0xFFFFFFFE` or `0xFFFFFFFF`
306                         return Err(AbortReason::IncorrectInputSequenceValue);
307                 }
308
309                 let transaction = msg.prevtx.as_transaction();
310                 let txid = transaction.txid();
311
312                 if let Some(tx_out) = transaction.output.get(msg.prevtx_out as usize) {
313                         if !tx_out.script_pubkey.is_witness_program() {
314                                 // The receiving node:
315                                 //  - MUST fail the negotiation if:
316                                 //     - the `scriptPubKey` is not a witness program
317                                 return Err(AbortReason::PrevTxOutInvalid);
318                         }
319
320                         if !self.prevtx_outpoints.insert(OutPoint { txid, vout: msg.prevtx_out }) {
321                                 // The receiving node:
322                                 //  - MUST fail the negotiation if:
323                                 //     - the `prevtx` and `prevtx_vout` are identical to a previously added
324                                 //       (and not removed) input's
325                                 return Err(AbortReason::PrevTxOutInvalid);
326                         }
327                 } else {
328                         // The receiving node:
329                         //  - MUST fail the negotiation if:
330                         //     - `prevtx_vout` is greater or equal to the number of outputs on `prevtx`
331                         return Err(AbortReason::PrevTxOutInvalid);
332                 }
333
334                 let prev_out = if let Some(prev_out) = transaction.output.get(msg.prevtx_out as usize) {
335                         prev_out.clone()
336                 } else {
337                         return Err(AbortReason::PrevTxOutInvalid);
338                 };
339                 match self.inputs.entry(msg.serial_id) {
340                         hash_map::Entry::Occupied(_) => {
341                                 // The receiving node:
342                                 //  - MUST fail the negotiation if:
343                                 //    - the `serial_id` is already included in the transaction
344                                 Err(AbortReason::DuplicateSerialId)
345                         },
346                         hash_map::Entry::Vacant(entry) => {
347                                 let prev_outpoint = OutPoint { txid, vout: msg.prevtx_out };
348                                 entry.insert(InteractiveTxInput {
349                                         serial_id: msg.serial_id,
350                                         input: TxIn {
351                                                 previous_output: prev_outpoint,
352                                                 sequence: Sequence(msg.sequence),
353                                                 ..Default::default()
354                                         },
355                                         prev_output: prev_out,
356                                 });
357                                 self.prevtx_outpoints.insert(prev_outpoint);
358                                 Ok(())
359                         },
360                 }
361         }
362
363         fn received_tx_remove_input(&mut self, msg: &msgs::TxRemoveInput) -> Result<(), AbortReason> {
364                 if !self.is_serial_id_valid_for_counterparty(&msg.serial_id) {
365                         return Err(AbortReason::IncorrectSerialIdParity);
366                 }
367
368                 self.inputs
369                         .remove(&msg.serial_id)
370                         // The receiving node:
371                         //  - MUST fail the negotiation if:
372                         //    - the input or output identified by the `serial_id` was not added by the sender
373                         //    - the `serial_id` does not correspond to a currently added input
374                         .ok_or(AbortReason::SerialIdUnknown)
375                         .map(|_| ())
376         }
377
378         fn received_tx_add_output(&mut self, msg: &msgs::TxAddOutput) -> Result<(), AbortReason> {
379                 // The receiving node:
380                 //  - MUST fail the negotiation if:
381                 //     - the serial_id has the wrong parity
382                 if !self.is_serial_id_valid_for_counterparty(&msg.serial_id) {
383                         return Err(AbortReason::IncorrectSerialIdParity);
384                 }
385
386                 self.received_tx_add_output_count += 1;
387                 if self.received_tx_add_output_count > MAX_RECEIVED_TX_ADD_OUTPUT_COUNT {
388                         // The receiving node:
389                         //  - MUST fail the negotiation if:
390                         //     - if has received 4096 `tx_add_output` messages during this negotiation
391                         return Err(AbortReason::ReceivedTooManyTxAddOutputs);
392                 }
393
394                 if msg.sats < msg.script.dust_value().to_sat() {
395                         // The receiving node:
396                         // - MUST fail the negotiation if:
397                         //              - the sats amount is less than the dust_limit
398                         return Err(AbortReason::BelowDustLimit);
399                 }
400
401                 // Check that adding this output would not cause the total output value to exceed the total
402                 // bitcoin supply.
403                 let mut outputs_value: u64 = 0;
404                 for output in self.outputs.iter() {
405                         outputs_value = outputs_value.saturating_add(output.1.tx_out.value);
406                 }
407                 if outputs_value.saturating_add(msg.sats) > TOTAL_BITCOIN_SUPPLY_SATOSHIS {
408                         // The receiving node:
409                         // - MUST fail the negotiation if:
410                         //              - the sats amount is greater than 2,100,000,000,000,000 (TOTAL_BITCOIN_SUPPLY_SATOSHIS)
411                         return Err(AbortReason::ExceededMaximumSatsAllowed);
412                 }
413
414                 // The receiving node:
415                 //   - MUST accept P2WSH, P2WPKH, P2TR scripts
416                 //   - MAY fail the negotiation if script is non-standard
417                 //
418                 // We can actually be a bit looser than the above as only witness version 0 has special
419                 // length-based standardness constraints to match similar consensus rules. All witness scripts
420                 // with witness versions V1 and up are always considered standard. Yes, the scripts can be
421                 // anyone-can-spend-able, but if our counterparty wants to add an output like that then it's none
422                 // of our concern really Â¯\_(ツ)_/¯
423                 //
424                 // TODO: The last check would be simplified when https://github.com/rust-bitcoin/rust-bitcoin/commit/1656e1a09a1959230e20af90d20789a4a8f0a31b
425                 // hits the next release of rust-bitcoin.
426                 if !(msg.script.is_v0_p2wpkh()
427                         || msg.script.is_v0_p2wsh()
428                         || (msg.script.is_witness_program()
429                                 && msg.script.witness_version().map(|v| v.to_num() >= 1).unwrap_or(false)))
430                 {
431                         return Err(AbortReason::InvalidOutputScript);
432                 }
433
434                 match self.outputs.entry(msg.serial_id) {
435                         hash_map::Entry::Occupied(_) => {
436                                 // The receiving node:
437                                 //  - MUST fail the negotiation if:
438                                 //    - the `serial_id` is already included in the transaction
439                                 Err(AbortReason::DuplicateSerialId)
440                         },
441                         hash_map::Entry::Vacant(entry) => {
442                                 entry.insert(InteractiveTxOutput {
443                                         serial_id: msg.serial_id,
444                                         tx_out: TxOut { value: msg.sats, script_pubkey: msg.script.clone() },
445                                 });
446                                 Ok(())
447                         },
448                 }
449         }
450
451         fn received_tx_remove_output(&mut self, msg: &msgs::TxRemoveOutput) -> Result<(), AbortReason> {
452                 if !self.is_serial_id_valid_for_counterparty(&msg.serial_id) {
453                         return Err(AbortReason::IncorrectSerialIdParity);
454                 }
455                 if self.outputs.remove(&msg.serial_id).is_some() {
456                         Ok(())
457                 } else {
458                         // The receiving node:
459                         //  - MUST fail the negotiation if:
460                         //    - the input or output identified by the `serial_id` was not added by the sender
461                         //    - the `serial_id` does not correspond to a currently added input
462                         Err(AbortReason::SerialIdUnknown)
463                 }
464         }
465
466         fn sent_tx_add_input(&mut self, msg: &msgs::TxAddInput) -> Result<(), AbortReason> {
467                 let tx = msg.prevtx.as_transaction();
468                 let input = TxIn {
469                         previous_output: OutPoint { txid: tx.txid(), vout: msg.prevtx_out },
470                         sequence: Sequence(msg.sequence),
471                         ..Default::default()
472                 };
473                 let prev_output =
474                         tx.output.get(msg.prevtx_out as usize).ok_or(AbortReason::PrevTxOutInvalid)?.clone();
475                 if !self.prevtx_outpoints.insert(input.previous_output) {
476                         // We have added an input that already exists
477                         return Err(AbortReason::PrevTxOutInvalid);
478                 }
479                 self.inputs.insert(
480                         msg.serial_id,
481                         InteractiveTxInput { serial_id: msg.serial_id, input, prev_output },
482                 );
483                 Ok(())
484         }
485
486         fn sent_tx_add_output(&mut self, msg: &msgs::TxAddOutput) -> Result<(), AbortReason> {
487                 self.outputs.insert(
488                         msg.serial_id,
489                         InteractiveTxOutput {
490                                 serial_id: msg.serial_id,
491                                 tx_out: TxOut { value: msg.sats, script_pubkey: msg.script.clone() },
492                         },
493                 );
494                 Ok(())
495         }
496
497         fn sent_tx_remove_input(&mut self, msg: &msgs::TxRemoveInput) -> Result<(), AbortReason> {
498                 self.inputs.remove(&msg.serial_id);
499                 Ok(())
500         }
501
502         fn sent_tx_remove_output(&mut self, msg: &msgs::TxRemoveOutput) -> Result<(), AbortReason> {
503                 self.outputs.remove(&msg.serial_id);
504                 Ok(())
505         }
506
507         fn check_counterparty_fees(
508                 &self, counterparty_fees_contributed: u64,
509         ) -> Result<(), AbortReason> {
510                 let counterparty_weight_contributed = self
511                         .remote_inputs_weight()
512                         .to_wu()
513                         .saturating_add(self.remote_outputs_weight().to_wu());
514                 let mut required_counterparty_contribution_fee =
515                         fee_for_weight(self.feerate_sat_per_kw, counterparty_weight_contributed);
516                 if !self.holder_is_initiator {
517                         // if is the non-initiator:
518                         //      - the initiator's fees do not cover the common fields (version, segwit marker + flag,
519                         //              input count, output count, locktime)
520                         let tx_common_fields_fee =
521                                 fee_for_weight(self.feerate_sat_per_kw, TX_COMMON_FIELDS_WEIGHT);
522                         required_counterparty_contribution_fee += tx_common_fields_fee;
523                 }
524                 if counterparty_fees_contributed < required_counterparty_contribution_fee {
525                         return Err(AbortReason::InsufficientFees);
526                 }
527                 Ok(())
528         }
529
530         fn validate_tx(self) -> Result<ConstructedTransaction, AbortReason> {
531                 // The receiving node:
532                 // MUST fail the negotiation if:
533
534                 // - the peer's total input satoshis is less than their outputs
535                 let remote_inputs_value = self.remote_inputs_value();
536                 let remote_outputs_value = self.remote_outputs_value();
537                 if remote_inputs_value < remote_outputs_value {
538                         return Err(AbortReason::OutputsValueExceedsInputsValue);
539                 }
540
541                 // - there are more than 252 inputs
542                 // - there are more than 252 outputs
543                 if self.inputs.len() > MAX_INPUTS_OUTPUTS_COUNT
544                         || self.outputs.len() > MAX_INPUTS_OUTPUTS_COUNT
545                 {
546                         return Err(AbortReason::ExceededNumberOfInputsOrOutputs);
547                 }
548
549                 // - the peer's paid feerate does not meet or exceed the agreed feerate (based on the minimum fee).
550                 self.check_counterparty_fees(remote_inputs_value.saturating_sub(remote_outputs_value))?;
551
552                 let constructed_tx = ConstructedTransaction::new(self);
553
554                 if constructed_tx.weight().to_wu() > MAX_STANDARD_TX_WEIGHT as u64 {
555                         return Err(AbortReason::TransactionTooLarge);
556                 }
557
558                 Ok(constructed_tx)
559         }
560 }
561
562 // The interactive transaction construction protocol allows two peers to collaboratively build a
563 // transaction for broadcast.
564 //
565 // The protocol is turn-based, so we define different states here that we store depending on whose
566 // turn it is to send the next message. The states are defined so that their types ensure we only
567 // perform actions (only send messages) via defined state transitions that do not violate the
568 // protocol.
569 //
570 // An example of a full negotiation and associated states follows:
571 //
572 //     +------------+                         +------------------+---- Holder state after message sent/received ----+
573 //     |            |--(1)- tx_add_input ---->|                  |                  SentChangeMsg                   +
574 //     |            |<-(2)- tx_complete ------|                  |                ReceivedTxComplete                +
575 //     |            |--(3)- tx_add_output --->|                  |                  SentChangeMsg                   +
576 //     |            |<-(4)- tx_complete ------|                  |                ReceivedTxComplete                +
577 //     |            |--(5)- tx_add_input ---->|                  |                  SentChangeMsg                   +
578 //     |   Holder   |<-(6)- tx_add_input -----|   Counterparty   |                ReceivedChangeMsg                 +
579 //     |            |--(7)- tx_remove_output >|                  |                  SentChangeMsg                   +
580 //     |            |<-(8)- tx_add_output ----|                  |                ReceivedChangeMsg                 +
581 //     |            |--(9)- tx_complete ----->|                  |                  SentTxComplete                  +
582 //     |            |<-(10) tx_complete ------|                  |                NegotiationComplete               +
583 //     +------------+                         +------------------+--------------------------------------------------+
584
585 /// Negotiation states that can send & receive `tx_(add|remove)_(input|output)` and `tx_complete`
586 trait State {}
587
588 /// Category of states where we have sent some message to the counterparty, and we are waiting for
589 /// a response.
590 trait SentMsgState: State {
591         fn into_negotiation_context(self) -> NegotiationContext;
592 }
593
594 /// Category of states that our counterparty has put us in after we receive a message from them.
595 trait ReceivedMsgState: State {
596         fn into_negotiation_context(self) -> NegotiationContext;
597 }
598
599 // This macro is a helper for implementing the above state traits for various states subsequently
600 // defined below the macro.
601 macro_rules! define_state {
602         (SENT_MSG_STATE, $state: ident, $doc: expr) => {
603                 define_state!($state, NegotiationContext, $doc);
604                 impl SentMsgState for $state {
605                         fn into_negotiation_context(self) -> NegotiationContext {
606                                 self.0
607                         }
608                 }
609         };
610         (RECEIVED_MSG_STATE, $state: ident, $doc: expr) => {
611                 define_state!($state, NegotiationContext, $doc);
612                 impl ReceivedMsgState for $state {
613                         fn into_negotiation_context(self) -> NegotiationContext {
614                                 self.0
615                         }
616                 }
617         };
618         ($state: ident, $inner: ident, $doc: expr) => {
619                 #[doc = $doc]
620                 #[derive(Debug)]
621                 struct $state($inner);
622                 impl State for $state {}
623         };
624 }
625
626 define_state!(
627         SENT_MSG_STATE,
628         SentChangeMsg,
629         "We have sent a message to the counterparty that has affected our negotiation state."
630 );
631 define_state!(
632         SENT_MSG_STATE,
633         SentTxComplete,
634         "We have sent a `tx_complete` message and are awaiting the counterparty's."
635 );
636 define_state!(
637         RECEIVED_MSG_STATE,
638         ReceivedChangeMsg,
639         "We have received a message from the counterparty that has affected our negotiation state."
640 );
641 define_state!(
642         RECEIVED_MSG_STATE,
643         ReceivedTxComplete,
644         "We have received a `tx_complete` message and the counterparty is awaiting ours."
645 );
646 define_state!(NegotiationComplete, ConstructedTransaction, "We have exchanged consecutive `tx_complete` messages with the counterparty and the transaction negotiation is complete.");
647 define_state!(
648         NegotiationAborted,
649         AbortReason,
650         "The negotiation has failed and cannot be continued."
651 );
652
653 type StateTransitionResult<S> = Result<S, AbortReason>;
654
655 trait StateTransition<NewState: State, TransitionData> {
656         fn transition(self, data: TransitionData) -> StateTransitionResult<NewState>;
657 }
658
659 // This macro helps define the legal transitions between the states above by implementing
660 // the `StateTransition` trait for each of the states that follow this declaration.
661 macro_rules! define_state_transitions {
662         (SENT_MSG_STATE, [$(DATA $data: ty, TRANSITION $transition: ident),+]) => {
663                 $(
664                         impl<S: SentMsgState> StateTransition<ReceivedChangeMsg, $data> for S {
665                                 fn transition(self, data: $data) -> StateTransitionResult<ReceivedChangeMsg> {
666                                         let mut context = self.into_negotiation_context();
667                                         context.$transition(data)?;
668                                         Ok(ReceivedChangeMsg(context))
669                                 }
670                         }
671                  )*
672         };
673         (RECEIVED_MSG_STATE, [$(DATA $data: ty, TRANSITION $transition: ident),+]) => {
674                 $(
675                         impl<S: ReceivedMsgState> StateTransition<SentChangeMsg, $data> for S {
676                                 fn transition(self, data: $data) -> StateTransitionResult<SentChangeMsg> {
677                                         let mut context = self.into_negotiation_context();
678                                         context.$transition(data)?;
679                                         Ok(SentChangeMsg(context))
680                                 }
681                         }
682                  )*
683         };
684         (TX_COMPLETE, $from_state: ident, $tx_complete_state: ident) => {
685                 impl StateTransition<NegotiationComplete, &msgs::TxComplete> for $tx_complete_state {
686                         fn transition(self, _data: &msgs::TxComplete) -> StateTransitionResult<NegotiationComplete> {
687                                 let context = self.into_negotiation_context();
688                                 let tx = context.validate_tx()?;
689                                 Ok(NegotiationComplete(tx))
690                         }
691                 }
692
693                 impl StateTransition<$tx_complete_state, &msgs::TxComplete> for $from_state {
694                         fn transition(self, _data: &msgs::TxComplete) -> StateTransitionResult<$tx_complete_state> {
695                                 Ok($tx_complete_state(self.into_negotiation_context()))
696                         }
697                 }
698         };
699 }
700
701 // State transitions when we have sent our counterparty some messages and are waiting for them
702 // to respond.
703 define_state_transitions!(SENT_MSG_STATE, [
704         DATA &msgs::TxAddInput, TRANSITION received_tx_add_input,
705         DATA &msgs::TxRemoveInput, TRANSITION received_tx_remove_input,
706         DATA &msgs::TxAddOutput, TRANSITION received_tx_add_output,
707         DATA &msgs::TxRemoveOutput, TRANSITION received_tx_remove_output
708 ]);
709 // State transitions when we have received some messages from our counterparty and we should
710 // respond.
711 define_state_transitions!(RECEIVED_MSG_STATE, [
712         DATA &msgs::TxAddInput, TRANSITION sent_tx_add_input,
713         DATA &msgs::TxRemoveInput, TRANSITION sent_tx_remove_input,
714         DATA &msgs::TxAddOutput, TRANSITION sent_tx_add_output,
715         DATA &msgs::TxRemoveOutput, TRANSITION sent_tx_remove_output
716 ]);
717 define_state_transitions!(TX_COMPLETE, SentChangeMsg, ReceivedTxComplete);
718 define_state_transitions!(TX_COMPLETE, ReceivedChangeMsg, SentTxComplete);
719
720 #[derive(Debug)]
721 enum StateMachine {
722         Indeterminate,
723         SentChangeMsg(SentChangeMsg),
724         ReceivedChangeMsg(ReceivedChangeMsg),
725         SentTxComplete(SentTxComplete),
726         ReceivedTxComplete(ReceivedTxComplete),
727         NegotiationComplete(NegotiationComplete),
728         NegotiationAborted(NegotiationAborted),
729 }
730
731 impl Default for StateMachine {
732         fn default() -> Self {
733                 Self::Indeterminate
734         }
735 }
736
737 // The `StateMachine` internally executes the actual transition between two states and keeps
738 // track of the current state. This macro defines _how_ those state transitions happen to
739 // update the internal state.
740 macro_rules! define_state_machine_transitions {
741         ($transition: ident, $msg: ty, [$(FROM $from_state: ident, TO $to_state: ident),+]) => {
742                 fn $transition(self, msg: $msg) -> StateMachine {
743                         match self {
744                                 $(
745                                         Self::$from_state(s) => match s.transition(msg) {
746                                                 Ok(new_state) => StateMachine::$to_state(new_state),
747                                                 Err(abort_reason) => StateMachine::NegotiationAborted(NegotiationAborted(abort_reason)),
748                                         }
749                                  )*
750                                 _ => StateMachine::NegotiationAborted(NegotiationAborted(AbortReason::UnexpectedCounterpartyMessage)),
751                         }
752                 }
753         };
754 }
755
756 impl StateMachine {
757         fn new(feerate_sat_per_kw: u32, is_initiator: bool, tx_locktime: AbsoluteLockTime) -> Self {
758                 let context = NegotiationContext {
759                         tx_locktime,
760                         holder_is_initiator: is_initiator,
761                         received_tx_add_input_count: 0,
762                         received_tx_add_output_count: 0,
763                         inputs: new_hash_map(),
764                         prevtx_outpoints: new_hash_set(),
765                         outputs: new_hash_map(),
766                         feerate_sat_per_kw,
767                 };
768                 if is_initiator {
769                         Self::ReceivedChangeMsg(ReceivedChangeMsg(context))
770                 } else {
771                         Self::SentChangeMsg(SentChangeMsg(context))
772                 }
773         }
774
775         // TxAddInput
776         define_state_machine_transitions!(sent_tx_add_input, &msgs::TxAddInput, [
777                 FROM ReceivedChangeMsg, TO SentChangeMsg,
778                 FROM ReceivedTxComplete, TO SentChangeMsg
779         ]);
780         define_state_machine_transitions!(received_tx_add_input, &msgs::TxAddInput, [
781                 FROM SentChangeMsg, TO ReceivedChangeMsg,
782                 FROM SentTxComplete, TO ReceivedChangeMsg
783         ]);
784
785         // TxAddOutput
786         define_state_machine_transitions!(sent_tx_add_output, &msgs::TxAddOutput, [
787                 FROM ReceivedChangeMsg, TO SentChangeMsg,
788                 FROM ReceivedTxComplete, TO SentChangeMsg
789         ]);
790         define_state_machine_transitions!(received_tx_add_output, &msgs::TxAddOutput, [
791                 FROM SentChangeMsg, TO ReceivedChangeMsg,
792                 FROM SentTxComplete, TO ReceivedChangeMsg
793         ]);
794
795         // TxRemoveInput
796         define_state_machine_transitions!(sent_tx_remove_input, &msgs::TxRemoveInput, [
797                 FROM ReceivedChangeMsg, TO SentChangeMsg,
798                 FROM ReceivedTxComplete, TO SentChangeMsg
799         ]);
800         define_state_machine_transitions!(received_tx_remove_input, &msgs::TxRemoveInput, [
801                 FROM SentChangeMsg, TO ReceivedChangeMsg,
802                 FROM SentTxComplete, TO ReceivedChangeMsg
803         ]);
804
805         // TxRemoveOutput
806         define_state_machine_transitions!(sent_tx_remove_output, &msgs::TxRemoveOutput, [
807                 FROM ReceivedChangeMsg, TO SentChangeMsg,
808                 FROM ReceivedTxComplete, TO SentChangeMsg
809         ]);
810         define_state_machine_transitions!(received_tx_remove_output, &msgs::TxRemoveOutput, [
811                 FROM SentChangeMsg, TO ReceivedChangeMsg,
812                 FROM SentTxComplete, TO ReceivedChangeMsg
813         ]);
814
815         // TxComplete
816         define_state_machine_transitions!(sent_tx_complete, &msgs::TxComplete, [
817                 FROM ReceivedChangeMsg, TO SentTxComplete,
818                 FROM ReceivedTxComplete, TO NegotiationComplete
819         ]);
820         define_state_machine_transitions!(received_tx_complete, &msgs::TxComplete, [
821                 FROM SentChangeMsg, TO ReceivedTxComplete,
822                 FROM SentTxComplete, TO NegotiationComplete
823         ]);
824 }
825
826 pub(crate) struct InteractiveTxConstructor {
827         state_machine: StateMachine,
828         channel_id: ChannelId,
829         inputs_to_contribute: Vec<(SerialId, TxIn, TransactionU16LenLimited)>,
830         outputs_to_contribute: Vec<(SerialId, TxOut)>,
831 }
832
833 pub(crate) enum InteractiveTxMessageSend {
834         TxAddInput(msgs::TxAddInput),
835         TxAddOutput(msgs::TxAddOutput),
836         TxComplete(msgs::TxComplete),
837 }
838
839 // This macro executes a state machine transition based on a provided action.
840 macro_rules! do_state_transition {
841         ($self: ident, $transition: ident, $msg: expr) => {{
842                 let state_machine = core::mem::take(&mut $self.state_machine);
843                 $self.state_machine = state_machine.$transition($msg);
844                 match &$self.state_machine {
845                         StateMachine::NegotiationAborted(state) => Err(state.0.clone()),
846                         _ => Ok(()),
847                 }
848         }};
849 }
850
851 fn generate_holder_serial_id<ES: Deref>(entropy_source: &ES, is_initiator: bool) -> SerialId
852 where
853         ES::Target: EntropySource,
854 {
855         let rand_bytes = entropy_source.get_secure_random_bytes();
856         let mut serial_id_bytes = [0u8; 8];
857         serial_id_bytes.copy_from_slice(&rand_bytes[..8]);
858         let mut serial_id = u64::from_be_bytes(serial_id_bytes);
859         if serial_id.is_for_initiator() != is_initiator {
860                 serial_id ^= 1;
861         }
862         serial_id
863 }
864
865 pub(crate) enum HandleTxCompleteValue {
866         SendTxMessage(InteractiveTxMessageSend),
867         SendTxComplete(InteractiveTxMessageSend, ConstructedTransaction),
868         NegotiationComplete(ConstructedTransaction),
869 }
870
871 impl InteractiveTxConstructor {
872         /// Instantiates a new `InteractiveTxConstructor`.
873         ///
874         /// A tuple is returned containing the newly instantiate `InteractiveTxConstructor` and optionally
875         /// an initial wrapped `Tx_` message which the holder needs to send to the counterparty.
876         pub fn new<ES: Deref>(
877                 entropy_source: &ES, channel_id: ChannelId, feerate_sat_per_kw: u32, is_initiator: bool,
878                 funding_tx_locktime: AbsoluteLockTime,
879                 inputs_to_contribute: Vec<(TxIn, TransactionU16LenLimited)>,
880                 outputs_to_contribute: Vec<TxOut>,
881         ) -> (Self, Option<InteractiveTxMessageSend>)
882         where
883                 ES::Target: EntropySource,
884         {
885                 let state_machine =
886                         StateMachine::new(feerate_sat_per_kw, is_initiator, funding_tx_locktime);
887                 let mut inputs_to_contribute: Vec<(SerialId, TxIn, TransactionU16LenLimited)> =
888                         inputs_to_contribute
889                                 .into_iter()
890                                 .map(|(input, tx)| {
891                                         let serial_id = generate_holder_serial_id(entropy_source, is_initiator);
892                                         (serial_id, input, tx)
893                                 })
894                                 .collect();
895                 // We'll sort by the randomly generated serial IDs, effectively shuffling the order of the inputs
896                 // as the user passed them to us to avoid leaking any potential categorization of transactions
897                 // before we pass any of the inputs to the counterparty.
898                 inputs_to_contribute.sort_unstable_by_key(|(serial_id, _, _)| *serial_id);
899                 let mut outputs_to_contribute: Vec<(SerialId, TxOut)> = outputs_to_contribute
900                         .into_iter()
901                         .map(|output| {
902                                 let serial_id = generate_holder_serial_id(entropy_source, is_initiator);
903                                 (serial_id, output)
904                         })
905                         .collect();
906                 // In the same manner and for the same rationale as the inputs above, we'll shuffle the outputs.
907                 outputs_to_contribute.sort_unstable_by_key(|(serial_id, _)| *serial_id);
908                 let mut constructor =
909                         Self { state_machine, channel_id, inputs_to_contribute, outputs_to_contribute };
910                 let message_send = if is_initiator {
911                         match constructor.maybe_send_message() {
912                                 Ok(msg_send) => Some(msg_send),
913                                 Err(_) => {
914                                         debug_assert!(
915                                                 false,
916                                                 "We should always be able to start our state machine successfully"
917                                         );
918                                         None
919                                 },
920                         }
921                 } else {
922                         None
923                 };
924                 (constructor, message_send)
925         }
926
927         fn maybe_send_message(&mut self) -> Result<InteractiveTxMessageSend, AbortReason> {
928                 // We first attempt to send inputs we want to add, then outputs. Once we are done sending
929                 // them both, then we always send tx_complete.
930                 if let Some((serial_id, input, prevtx)) = self.inputs_to_contribute.pop() {
931                         let msg = msgs::TxAddInput {
932                                 channel_id: self.channel_id,
933                                 serial_id,
934                                 prevtx,
935                                 prevtx_out: input.previous_output.vout,
936                                 sequence: input.sequence.to_consensus_u32(),
937                         };
938                         do_state_transition!(self, sent_tx_add_input, &msg)?;
939                         Ok(InteractiveTxMessageSend::TxAddInput(msg))
940                 } else if let Some((serial_id, output)) = self.outputs_to_contribute.pop() {
941                         let msg = msgs::TxAddOutput {
942                                 channel_id: self.channel_id,
943                                 serial_id,
944                                 sats: output.value,
945                                 script: output.script_pubkey,
946                         };
947                         do_state_transition!(self, sent_tx_add_output, &msg)?;
948                         Ok(InteractiveTxMessageSend::TxAddOutput(msg))
949                 } else {
950                         let msg = msgs::TxComplete { channel_id: self.channel_id };
951                         do_state_transition!(self, sent_tx_complete, &msg)?;
952                         Ok(InteractiveTxMessageSend::TxComplete(msg))
953                 }
954         }
955
956         pub fn handle_tx_add_input(
957                 &mut self, msg: &msgs::TxAddInput,
958         ) -> Result<InteractiveTxMessageSend, AbortReason> {
959                 do_state_transition!(self, received_tx_add_input, msg)?;
960                 self.maybe_send_message()
961         }
962
963         pub fn handle_tx_remove_input(
964                 &mut self, msg: &msgs::TxRemoveInput,
965         ) -> Result<InteractiveTxMessageSend, AbortReason> {
966                 do_state_transition!(self, received_tx_remove_input, msg)?;
967                 self.maybe_send_message()
968         }
969
970         pub fn handle_tx_add_output(
971                 &mut self, msg: &msgs::TxAddOutput,
972         ) -> Result<InteractiveTxMessageSend, AbortReason> {
973                 do_state_transition!(self, received_tx_add_output, msg)?;
974                 self.maybe_send_message()
975         }
976
977         pub fn handle_tx_remove_output(
978                 &mut self, msg: &msgs::TxRemoveOutput,
979         ) -> Result<InteractiveTxMessageSend, AbortReason> {
980                 do_state_transition!(self, received_tx_remove_output, msg)?;
981                 self.maybe_send_message()
982         }
983
984         pub fn handle_tx_complete(
985                 &mut self, msg: &msgs::TxComplete,
986         ) -> Result<HandleTxCompleteValue, AbortReason> {
987                 do_state_transition!(self, received_tx_complete, msg)?;
988                 match &self.state_machine {
989                         StateMachine::ReceivedTxComplete(_) => {
990                                 let msg_send = self.maybe_send_message()?;
991                                 match &self.state_machine {
992                                         StateMachine::NegotiationComplete(s) => {
993                                                 Ok(HandleTxCompleteValue::SendTxComplete(msg_send, s.0.clone()))
994                                         },
995                                         StateMachine::SentChangeMsg(_) => {
996                                                 Ok(HandleTxCompleteValue::SendTxMessage(msg_send))
997                                         }, // We either had an input or output to contribute.
998                                         _ => {
999                                                 debug_assert!(false, "We cannot transition to any other states after receiving `tx_complete` and responding");
1000                                                 Err(AbortReason::InvalidStateTransition)
1001                                         },
1002                                 }
1003                         },
1004                         StateMachine::NegotiationComplete(s) => {
1005                                 Ok(HandleTxCompleteValue::NegotiationComplete(s.0.clone()))
1006                         },
1007                         _ => {
1008                                 debug_assert!(
1009                                         false,
1010                                         "We cannot transition to any other states after receiving `tx_complete`"
1011                                 );
1012                                 Err(AbortReason::InvalidStateTransition)
1013                         },
1014                 }
1015         }
1016 }
1017
1018 #[cfg(test)]
1019 mod tests {
1020         use crate::chain::chaininterface::{fee_for_weight, FEERATE_FLOOR_SATS_PER_KW};
1021         use crate::ln::channel::TOTAL_BITCOIN_SUPPLY_SATOSHIS;
1022         use crate::ln::interactivetxs::{
1023                 generate_holder_serial_id, AbortReason, HandleTxCompleteValue, InteractiveTxConstructor,
1024                 InteractiveTxMessageSend, MAX_INPUTS_OUTPUTS_COUNT, MAX_RECEIVED_TX_ADD_INPUT_COUNT,
1025                 MAX_RECEIVED_TX_ADD_OUTPUT_COUNT,
1026         };
1027         use crate::ln::types::ChannelId;
1028         use crate::sign::EntropySource;
1029         use crate::util::atomic_counter::AtomicCounter;
1030         use crate::util::ser::TransactionU16LenLimited;
1031         use bitcoin::blockdata::opcodes;
1032         use bitcoin::blockdata::script::Builder;
1033         use bitcoin::hashes::Hash;
1034         use bitcoin::key::UntweakedPublicKey;
1035         use bitcoin::secp256k1::{KeyPair, Secp256k1};
1036         use bitcoin::{
1037                 absolute::LockTime as AbsoluteLockTime, OutPoint, Sequence, Transaction, TxIn, TxOut,
1038         };
1039         use bitcoin::{PubkeyHash, ScriptBuf, WPubkeyHash, WScriptHash};
1040         use core::ops::Deref;
1041
1042         use super::{
1043                 get_output_weight, P2TR_INPUT_WEIGHT_LOWER_BOUND, P2WPKH_INPUT_WEIGHT_LOWER_BOUND,
1044                 P2WSH_INPUT_WEIGHT_LOWER_BOUND, TX_COMMON_FIELDS_WEIGHT,
1045         };
1046
1047         const TEST_FEERATE_SATS_PER_KW: u32 = FEERATE_FLOOR_SATS_PER_KW * 10;
1048
1049         // A simple entropy source that works based on an atomic counter.
1050         struct TestEntropySource(AtomicCounter);
1051         impl EntropySource for TestEntropySource {
1052                 fn get_secure_random_bytes(&self) -> [u8; 32] {
1053                         let mut res = [0u8; 32];
1054                         let increment = self.0.get_increment();
1055                         for i in 0..32 {
1056                                 // Rotate the increment value by 'i' bits to the right, to avoid clashes
1057                                 // when `generate_local_serial_id` does a parity flip on consecutive calls for the
1058                                 // same party.
1059                                 let rotated_increment = increment.rotate_right(i as u32);
1060                                 res[i] = (rotated_increment & 0xff) as u8;
1061                         }
1062                         res
1063                 }
1064         }
1065
1066         // An entropy source that deliberately returns you the same seed every time. We use this
1067         // to test if the constructor would catch inputs/outputs that are attempting to be added
1068         // with duplicate serial ids.
1069         struct DuplicateEntropySource;
1070         impl EntropySource for DuplicateEntropySource {
1071                 fn get_secure_random_bytes(&self) -> [u8; 32] {
1072                         let mut res = [0u8; 32];
1073                         let count = 1u64;
1074                         res[0..8].copy_from_slice(&count.to_be_bytes());
1075                         res
1076                 }
1077         }
1078
1079         #[derive(Debug, PartialEq, Eq)]
1080         enum ErrorCulprit {
1081                 NodeA,
1082                 NodeB,
1083                 // Some error values are only checked at the end of the negotiation and are not easy to attribute
1084                 // to a particular party. Both parties would indicate an `AbortReason` in this case.
1085                 // e.g. Exceeded max inputs and outputs after negotiation.
1086                 Indeterminate,
1087         }
1088
1089         struct TestSession {
1090                 description: &'static str,
1091                 inputs_a: Vec<(TxIn, TransactionU16LenLimited)>,
1092                 outputs_a: Vec<TxOut>,
1093                 inputs_b: Vec<(TxIn, TransactionU16LenLimited)>,
1094                 outputs_b: Vec<TxOut>,
1095                 expect_error: Option<(AbortReason, ErrorCulprit)>,
1096         }
1097
1098         fn do_test_interactive_tx_constructor(session: TestSession) {
1099                 let entropy_source = TestEntropySource(AtomicCounter::new());
1100                 do_test_interactive_tx_constructor_internal(session, &&entropy_source);
1101         }
1102
1103         fn do_test_interactive_tx_constructor_with_entropy_source<ES: Deref>(
1104                 session: TestSession, entropy_source: ES,
1105         ) where
1106                 ES::Target: EntropySource,
1107         {
1108                 do_test_interactive_tx_constructor_internal(session, &entropy_source);
1109         }
1110
1111         fn do_test_interactive_tx_constructor_internal<ES: Deref>(
1112                 session: TestSession, entropy_source: &ES,
1113         ) where
1114                 ES::Target: EntropySource,
1115         {
1116                 let channel_id = ChannelId(entropy_source.get_secure_random_bytes());
1117                 let tx_locktime = AbsoluteLockTime::from_height(1337).unwrap();
1118
1119                 let (mut constructor_a, first_message_a) = InteractiveTxConstructor::new(
1120                         entropy_source,
1121                         channel_id,
1122                         TEST_FEERATE_SATS_PER_KW,
1123                         true,
1124                         tx_locktime,
1125                         session.inputs_a,
1126                         session.outputs_a,
1127                 );
1128                 let (mut constructor_b, first_message_b) = InteractiveTxConstructor::new(
1129                         entropy_source,
1130                         channel_id,
1131                         TEST_FEERATE_SATS_PER_KW,
1132                         false,
1133                         tx_locktime,
1134                         session.inputs_b,
1135                         session.outputs_b,
1136                 );
1137
1138                 let handle_message_send =
1139                         |msg: InteractiveTxMessageSend, for_constructor: &mut InteractiveTxConstructor| {
1140                                 match msg {
1141                                         InteractiveTxMessageSend::TxAddInput(msg) => for_constructor
1142                                                 .handle_tx_add_input(&msg)
1143                                                 .map(|msg_send| (Some(msg_send), None)),
1144                                         InteractiveTxMessageSend::TxAddOutput(msg) => for_constructor
1145                                                 .handle_tx_add_output(&msg)
1146                                                 .map(|msg_send| (Some(msg_send), None)),
1147                                         InteractiveTxMessageSend::TxComplete(msg) => {
1148                                                 for_constructor.handle_tx_complete(&msg).map(|value| match value {
1149                                                         HandleTxCompleteValue::SendTxMessage(msg_send) => {
1150                                                                 (Some(msg_send), None)
1151                                                         },
1152                                                         HandleTxCompleteValue::SendTxComplete(msg_send, tx) => {
1153                                                                 (Some(msg_send), Some(tx))
1154                                                         },
1155                                                         HandleTxCompleteValue::NegotiationComplete(tx) => (None, Some(tx)),
1156                                                 })
1157                                         },
1158                                 }
1159                         };
1160
1161                 assert!(first_message_b.is_none());
1162                 let mut message_send_a = first_message_a;
1163                 let mut message_send_b = None;
1164                 let mut final_tx_a = None;
1165                 let mut final_tx_b = None;
1166                 while final_tx_a.is_none() || final_tx_b.is_none() {
1167                         if let Some(message_send_a) = message_send_a.take() {
1168                                 match handle_message_send(message_send_a, &mut constructor_b) {
1169                                         Ok((msg_send, final_tx)) => {
1170                                                 message_send_b = msg_send;
1171                                                 final_tx_b = final_tx;
1172                                         },
1173                                         Err(abort_reason) => {
1174                                                 let error_culprit = match abort_reason {
1175                                                         AbortReason::ExceededNumberOfInputsOrOutputs => {
1176                                                                 ErrorCulprit::Indeterminate
1177                                                         },
1178                                                         _ => ErrorCulprit::NodeA,
1179                                                 };
1180                                                 assert_eq!(
1181                                                         Some((abort_reason, error_culprit)),
1182                                                         session.expect_error,
1183                                                         "Test: {}",
1184                                                         session.description
1185                                                 );
1186                                                 assert!(message_send_b.is_none());
1187                                                 return;
1188                                         },
1189                                 }
1190                         }
1191                         if let Some(message_send_b) = message_send_b.take() {
1192                                 match handle_message_send(message_send_b, &mut constructor_a) {
1193                                         Ok((msg_send, final_tx)) => {
1194                                                 message_send_a = msg_send;
1195                                                 final_tx_a = final_tx;
1196                                         },
1197                                         Err(abort_reason) => {
1198                                                 let error_culprit = match abort_reason {
1199                                                         AbortReason::ExceededNumberOfInputsOrOutputs => {
1200                                                                 ErrorCulprit::Indeterminate
1201                                                         },
1202                                                         _ => ErrorCulprit::NodeB,
1203                                                 };
1204                                                 assert_eq!(
1205                                                         Some((abort_reason, error_culprit)),
1206                                                         session.expect_error,
1207                                                         "Test: {}",
1208                                                         session.description
1209                                                 );
1210                                                 assert!(message_send_a.is_none());
1211                                                 return;
1212                                         },
1213                                 }
1214                         }
1215                 }
1216                 assert!(message_send_a.is_none());
1217                 assert!(message_send_b.is_none());
1218                 assert_eq!(final_tx_a.unwrap().into_unsigned_tx(), final_tx_b.unwrap().into_unsigned_tx());
1219                 assert!(session.expect_error.is_none(), "Test: {}", session.description);
1220         }
1221
1222         #[derive(Debug, Clone, Copy)]
1223         enum TestOutput {
1224                 P2WPKH(u64),
1225                 P2WSH(u64),
1226                 P2TR(u64),
1227                 // Non-witness type to test rejection.
1228                 P2PKH(u64),
1229         }
1230
1231         fn generate_tx(outputs: &[TestOutput]) -> Transaction {
1232                 generate_tx_with_locktime(outputs, 1337)
1233         }
1234
1235         fn generate_txout(output: &TestOutput) -> TxOut {
1236                 let secp_ctx = Secp256k1::new();
1237                 let (value, script_pubkey) = match output {
1238                         TestOutput::P2WPKH(value) => {
1239                                 (*value, ScriptBuf::new_v0_p2wpkh(&WPubkeyHash::from_slice(&[1; 20]).unwrap()))
1240                         },
1241                         TestOutput::P2WSH(value) => {
1242                                 (*value, ScriptBuf::new_v0_p2wsh(&WScriptHash::from_slice(&[2; 32]).unwrap()))
1243                         },
1244                         TestOutput::P2TR(value) => (
1245                                 *value,
1246                                 ScriptBuf::new_v1_p2tr(
1247                                         &secp_ctx,
1248                                         UntweakedPublicKey::from_keypair(
1249                                                 &KeyPair::from_seckey_slice(&secp_ctx, &[3; 32]).unwrap(),
1250                                         )
1251                                         .0,
1252                                         None,
1253                                 ),
1254                         ),
1255                         TestOutput::P2PKH(value) => {
1256                                 (*value, ScriptBuf::new_p2pkh(&PubkeyHash::from_slice(&[4; 20]).unwrap()))
1257                         },
1258                 };
1259
1260                 TxOut { value, script_pubkey }
1261         }
1262
1263         fn generate_tx_with_locktime(outputs: &[TestOutput], locktime: u32) -> Transaction {
1264                 Transaction {
1265                         version: 2,
1266                         lock_time: AbsoluteLockTime::from_height(locktime).unwrap(),
1267                         input: vec![TxIn { ..Default::default() }],
1268                         output: outputs.iter().map(generate_txout).collect(),
1269                 }
1270         }
1271
1272         fn generate_inputs(outputs: &[TestOutput]) -> Vec<(TxIn, TransactionU16LenLimited)> {
1273                 let tx = generate_tx(outputs);
1274                 let txid = tx.txid();
1275                 tx.output
1276                         .iter()
1277                         .enumerate()
1278                         .map(|(idx, _)| {
1279                                 let input = TxIn {
1280                                         previous_output: OutPoint { txid, vout: idx as u32 },
1281                                         script_sig: Default::default(),
1282                                         sequence: Sequence::ENABLE_RBF_NO_LOCKTIME,
1283                                         witness: Default::default(),
1284                                 };
1285                                 (input, TransactionU16LenLimited::new(tx.clone()).unwrap())
1286                         })
1287                         .collect()
1288         }
1289
1290         fn generate_p2wsh_script_pubkey() -> ScriptBuf {
1291                 Builder::new().push_opcode(opcodes::OP_TRUE).into_script().to_v0_p2wsh()
1292         }
1293
1294         fn generate_p2wpkh_script_pubkey() -> ScriptBuf {
1295                 ScriptBuf::new_v0_p2wpkh(&WPubkeyHash::from_slice(&[1; 20]).unwrap())
1296         }
1297
1298         fn generate_outputs(outputs: &[TestOutput]) -> Vec<TxOut> {
1299                 outputs.iter().map(generate_txout).collect()
1300         }
1301
1302         fn generate_fixed_number_of_inputs(count: u16) -> Vec<(TxIn, TransactionU16LenLimited)> {
1303                 // Generate transactions with a total `count` number of outputs such that no transaction has a
1304                 // serialized length greater than u16::MAX.
1305                 let max_outputs_per_prevtx = 1_500;
1306                 let mut remaining = count;
1307                 let mut inputs: Vec<(TxIn, TransactionU16LenLimited)> = Vec::with_capacity(count as usize);
1308
1309                 while remaining > 0 {
1310                         let tx_output_count = remaining.min(max_outputs_per_prevtx);
1311                         remaining -= tx_output_count;
1312
1313                         // Use unique locktime for each tx so outpoints are different across transactions
1314                         let tx = generate_tx_with_locktime(
1315                                 &vec![TestOutput::P2WPKH(1_000_000); tx_output_count as usize],
1316                                 (1337 + remaining).into(),
1317                         );
1318                         let txid = tx.txid();
1319
1320                         let mut temp: Vec<(TxIn, TransactionU16LenLimited)> = tx
1321                                 .output
1322                                 .iter()
1323                                 .enumerate()
1324                                 .map(|(idx, _)| {
1325                                         let input = TxIn {
1326                                                 previous_output: OutPoint { txid, vout: idx as u32 },
1327                                                 script_sig: Default::default(),
1328                                                 sequence: Sequence::ENABLE_RBF_NO_LOCKTIME,
1329                                                 witness: Default::default(),
1330                                         };
1331                                         (input, TransactionU16LenLimited::new(tx.clone()).unwrap())
1332                                 })
1333                                 .collect();
1334
1335                         inputs.append(&mut temp);
1336                 }
1337
1338                 inputs
1339         }
1340
1341         fn generate_fixed_number_of_outputs(count: u16) -> Vec<TxOut> {
1342                 // Set a constant value for each TxOut
1343                 generate_outputs(&vec![TestOutput::P2WPKH(1_000_000); count as usize])
1344         }
1345
1346         fn generate_p2sh_script_pubkey() -> ScriptBuf {
1347                 Builder::new().push_opcode(opcodes::OP_TRUE).into_script().to_p2sh()
1348         }
1349
1350         fn generate_non_witness_output(value: u64) -> TxOut {
1351                 TxOut { value, script_pubkey: generate_p2sh_script_pubkey() }
1352         }
1353
1354         #[test]
1355         fn test_interactive_tx_constructor() {
1356                 do_test_interactive_tx_constructor(TestSession {
1357                         description: "No contributions",
1358                         inputs_a: vec![],
1359                         outputs_a: vec![],
1360                         inputs_b: vec![],
1361                         outputs_b: vec![],
1362                         expect_error: Some((AbortReason::InsufficientFees, ErrorCulprit::NodeA)),
1363                 });
1364                 do_test_interactive_tx_constructor(TestSession {
1365                         description: "Single contribution, no initiator inputs",
1366                         inputs_a: vec![],
1367                         outputs_a: generate_outputs(&[TestOutput::P2WPKH(1_000_000)]),
1368                         inputs_b: vec![],
1369                         outputs_b: vec![],
1370                         expect_error: Some((AbortReason::OutputsValueExceedsInputsValue, ErrorCulprit::NodeA)),
1371                 });
1372                 do_test_interactive_tx_constructor(TestSession {
1373                         description: "Single contribution, no initiator outputs",
1374                         inputs_a: generate_inputs(&[TestOutput::P2WPKH(1_000_000)]),
1375                         outputs_a: vec![],
1376                         inputs_b: vec![],
1377                         outputs_b: vec![],
1378                         expect_error: None,
1379                 });
1380                 do_test_interactive_tx_constructor(TestSession {
1381                         description: "Single contribution, no fees",
1382                         inputs_a: generate_inputs(&[TestOutput::P2WPKH(1_000_000)]),
1383                         outputs_a: generate_outputs(&[TestOutput::P2WPKH(1_000_000)]),
1384                         inputs_b: vec![],
1385                         outputs_b: vec![],
1386                         expect_error: Some((AbortReason::InsufficientFees, ErrorCulprit::NodeA)),
1387                 });
1388                 let p2wpkh_fee = fee_for_weight(TEST_FEERATE_SATS_PER_KW, P2WPKH_INPUT_WEIGHT_LOWER_BOUND);
1389                 let outputs_fee = fee_for_weight(
1390                         TEST_FEERATE_SATS_PER_KW,
1391                         get_output_weight(&generate_p2wpkh_script_pubkey()).to_wu(),
1392                 );
1393                 let tx_common_fields_fee =
1394                         fee_for_weight(TEST_FEERATE_SATS_PER_KW, TX_COMMON_FIELDS_WEIGHT);
1395                 do_test_interactive_tx_constructor(TestSession {
1396                         description: "Single contribution, with P2WPKH input, insufficient fees",
1397                         inputs_a: generate_inputs(&[TestOutput::P2WPKH(1_000_000)]),
1398                         outputs_a: generate_outputs(&[TestOutput::P2WPKH(
1399                                 1_000_000 - p2wpkh_fee - outputs_fee - tx_common_fields_fee + 1, /* makes fees insuffcient for initiator */
1400                         )]),
1401                         inputs_b: vec![],
1402                         outputs_b: vec![],
1403                         expect_error: Some((AbortReason::InsufficientFees, ErrorCulprit::NodeA)),
1404                 });
1405                 do_test_interactive_tx_constructor(TestSession {
1406                         description: "Single contribution with P2WPKH input, sufficient fees",
1407                         inputs_a: generate_inputs(&[TestOutput::P2WPKH(1_000_000)]),
1408                         outputs_a: generate_outputs(&[TestOutput::P2WPKH(
1409                                 1_000_000 - p2wpkh_fee - outputs_fee - tx_common_fields_fee,
1410                         )]),
1411                         inputs_b: vec![],
1412                         outputs_b: vec![],
1413                         expect_error: None,
1414                 });
1415                 let p2wsh_fee = fee_for_weight(TEST_FEERATE_SATS_PER_KW, P2WSH_INPUT_WEIGHT_LOWER_BOUND);
1416                 do_test_interactive_tx_constructor(TestSession {
1417                         description: "Single contribution, with P2WSH input, insufficient fees",
1418                         inputs_a: generate_inputs(&[TestOutput::P2WSH(1_000_000)]),
1419                         outputs_a: generate_outputs(&[TestOutput::P2WPKH(
1420                                 1_000_000 - p2wsh_fee - outputs_fee - tx_common_fields_fee + 1, /* makes fees insuffcient for initiator */
1421                         )]),
1422                         inputs_b: vec![],
1423                         outputs_b: vec![],
1424                         expect_error: Some((AbortReason::InsufficientFees, ErrorCulprit::NodeA)),
1425                 });
1426                 do_test_interactive_tx_constructor(TestSession {
1427                         description: "Single contribution with P2WSH input, sufficient fees",
1428                         inputs_a: generate_inputs(&[TestOutput::P2WSH(1_000_000)]),
1429                         outputs_a: generate_outputs(&[TestOutput::P2WPKH(
1430                                 1_000_000 - p2wsh_fee - outputs_fee - tx_common_fields_fee,
1431                         )]),
1432                         inputs_b: vec![],
1433                         outputs_b: vec![],
1434                         expect_error: None,
1435                 });
1436                 let p2tr_fee = fee_for_weight(TEST_FEERATE_SATS_PER_KW, P2TR_INPUT_WEIGHT_LOWER_BOUND);
1437                 do_test_interactive_tx_constructor(TestSession {
1438                         description: "Single contribution, with P2TR input, insufficient fees",
1439                         inputs_a: generate_inputs(&[TestOutput::P2TR(1_000_000)]),
1440                         outputs_a: generate_outputs(&[TestOutput::P2WPKH(
1441                                 1_000_000 - p2tr_fee - outputs_fee - tx_common_fields_fee + 1, /* makes fees insuffcient for initiator */
1442                         )]),
1443                         inputs_b: vec![],
1444                         outputs_b: vec![],
1445                         expect_error: Some((AbortReason::InsufficientFees, ErrorCulprit::NodeA)),
1446                 });
1447                 do_test_interactive_tx_constructor(TestSession {
1448                         description: "Single contribution with P2TR input, sufficient fees",
1449                         inputs_a: generate_inputs(&[TestOutput::P2TR(1_000_000)]),
1450                         outputs_a: generate_outputs(&[TestOutput::P2WPKH(
1451                                 1_000_000 - p2tr_fee - outputs_fee - tx_common_fields_fee,
1452                         )]),
1453                         inputs_b: vec![],
1454                         outputs_b: vec![],
1455                         expect_error: None,
1456                 });
1457                 do_test_interactive_tx_constructor(TestSession {
1458                         description: "Initiator contributes sufficient fees, but non-initiator does not",
1459                         inputs_a: generate_inputs(&[TestOutput::P2WPKH(1_000_000)]),
1460                         outputs_a: vec![],
1461                         inputs_b: generate_inputs(&[TestOutput::P2WPKH(100_000)]),
1462                         outputs_b: generate_outputs(&[TestOutput::P2WPKH(100_000)]),
1463                         expect_error: Some((AbortReason::InsufficientFees, ErrorCulprit::NodeB)),
1464                 });
1465                 do_test_interactive_tx_constructor(TestSession {
1466                         description: "Multi-input-output contributions from both sides",
1467                         inputs_a: generate_inputs(&[TestOutput::P2WPKH(1_000_000); 2]),
1468                         outputs_a: generate_outputs(&[
1469                                 TestOutput::P2WPKH(1_000_000),
1470                                 TestOutput::P2WPKH(200_000),
1471                         ]),
1472                         inputs_b: generate_inputs(&[
1473                                 TestOutput::P2WPKH(1_000_000),
1474                                 TestOutput::P2WPKH(500_000),
1475                         ]),
1476                         outputs_b: generate_outputs(&[
1477                                 TestOutput::P2WPKH(1_000_000),
1478                                 TestOutput::P2WPKH(400_000),
1479                         ]),
1480                         expect_error: None,
1481                 });
1482
1483                 do_test_interactive_tx_constructor(TestSession {
1484                         description: "Prevout from initiator is not a witness program",
1485                         inputs_a: generate_inputs(&[TestOutput::P2PKH(1_000_000)]),
1486                         outputs_a: vec![],
1487                         inputs_b: vec![],
1488                         outputs_b: vec![],
1489                         expect_error: Some((AbortReason::PrevTxOutInvalid, ErrorCulprit::NodeA)),
1490                 });
1491
1492                 let tx =
1493                         TransactionU16LenLimited::new(generate_tx(&[TestOutput::P2WPKH(1_000_000)])).unwrap();
1494                 let invalid_sequence_input = TxIn {
1495                         previous_output: OutPoint { txid: tx.as_transaction().txid(), vout: 0 },
1496                         ..Default::default()
1497                 };
1498                 do_test_interactive_tx_constructor(TestSession {
1499                         description: "Invalid input sequence from initiator",
1500                         inputs_a: vec![(invalid_sequence_input, tx.clone())],
1501                         outputs_a: generate_outputs(&[TestOutput::P2WPKH(1_000_000)]),
1502                         inputs_b: vec![],
1503                         outputs_b: vec![],
1504                         expect_error: Some((AbortReason::IncorrectInputSequenceValue, ErrorCulprit::NodeA)),
1505                 });
1506                 let duplicate_input = TxIn {
1507                         previous_output: OutPoint { txid: tx.as_transaction().txid(), vout: 0 },
1508                         sequence: Sequence::ENABLE_RBF_NO_LOCKTIME,
1509                         ..Default::default()
1510                 };
1511                 do_test_interactive_tx_constructor(TestSession {
1512                         description: "Duplicate prevout from initiator",
1513                         inputs_a: vec![(duplicate_input.clone(), tx.clone()), (duplicate_input, tx.clone())],
1514                         outputs_a: generate_outputs(&[TestOutput::P2WPKH(1_000_000)]),
1515                         inputs_b: vec![],
1516                         outputs_b: vec![],
1517                         expect_error: Some((AbortReason::PrevTxOutInvalid, ErrorCulprit::NodeB)),
1518                 });
1519                 let duplicate_input = TxIn {
1520                         previous_output: OutPoint { txid: tx.as_transaction().txid(), vout: 0 },
1521                         sequence: Sequence::ENABLE_RBF_NO_LOCKTIME,
1522                         ..Default::default()
1523                 };
1524                 do_test_interactive_tx_constructor(TestSession {
1525                         description: "Non-initiator uses same prevout as initiator",
1526                         inputs_a: vec![(duplicate_input.clone(), tx.clone())],
1527                         outputs_a: generate_outputs(&[TestOutput::P2WPKH(1_000_000)]),
1528                         inputs_b: vec![(duplicate_input.clone(), tx.clone())],
1529                         outputs_b: vec![],
1530                         expect_error: Some((AbortReason::PrevTxOutInvalid, ErrorCulprit::NodeA)),
1531                 });
1532                 do_test_interactive_tx_constructor(TestSession {
1533                         description: "Initiator sends too many TxAddInputs",
1534                         inputs_a: generate_fixed_number_of_inputs(MAX_RECEIVED_TX_ADD_INPUT_COUNT + 1),
1535                         outputs_a: vec![],
1536                         inputs_b: vec![],
1537                         outputs_b: vec![],
1538                         expect_error: Some((AbortReason::ReceivedTooManyTxAddInputs, ErrorCulprit::NodeA)),
1539                 });
1540                 do_test_interactive_tx_constructor_with_entropy_source(
1541                         TestSession {
1542                                 // We use a deliberately bad entropy source, `DuplicateEntropySource` to simulate this.
1543                                 description: "Attempt to queue up two inputs with duplicate serial ids",
1544                                 inputs_a: generate_fixed_number_of_inputs(2),
1545                                 outputs_a: vec![],
1546                                 inputs_b: vec![],
1547                                 outputs_b: vec![],
1548                                 expect_error: Some((AbortReason::DuplicateSerialId, ErrorCulprit::NodeA)),
1549                         },
1550                         &DuplicateEntropySource,
1551                 );
1552                 do_test_interactive_tx_constructor(TestSession {
1553                         description: "Initiator sends too many TxAddOutputs",
1554                         inputs_a: vec![],
1555                         outputs_a: generate_fixed_number_of_outputs(MAX_RECEIVED_TX_ADD_OUTPUT_COUNT + 1),
1556                         inputs_b: vec![],
1557                         outputs_b: vec![],
1558                         expect_error: Some((AbortReason::ReceivedTooManyTxAddOutputs, ErrorCulprit::NodeA)),
1559                 });
1560                 do_test_interactive_tx_constructor(TestSession {
1561                         description: "Initiator sends an output below dust value",
1562                         inputs_a: vec![],
1563                         outputs_a: generate_outputs(&[TestOutput::P2WSH(
1564                                 generate_p2wsh_script_pubkey().dust_value().to_sat() - 1,
1565                         )]),
1566                         inputs_b: vec![],
1567                         outputs_b: vec![],
1568                         expect_error: Some((AbortReason::BelowDustLimit, ErrorCulprit::NodeA)),
1569                 });
1570                 do_test_interactive_tx_constructor(TestSession {
1571                         description: "Initiator sends an output above maximum sats allowed",
1572                         inputs_a: vec![],
1573                         outputs_a: generate_outputs(&[TestOutput::P2WPKH(TOTAL_BITCOIN_SUPPLY_SATOSHIS + 1)]),
1574                         inputs_b: vec![],
1575                         outputs_b: vec![],
1576                         expect_error: Some((AbortReason::ExceededMaximumSatsAllowed, ErrorCulprit::NodeA)),
1577                 });
1578                 do_test_interactive_tx_constructor(TestSession {
1579                         description: "Initiator sends an output without a witness program",
1580                         inputs_a: vec![],
1581                         outputs_a: vec![generate_non_witness_output(1_000_000)],
1582                         inputs_b: vec![],
1583                         outputs_b: vec![],
1584                         expect_error: Some((AbortReason::InvalidOutputScript, ErrorCulprit::NodeA)),
1585                 });
1586                 do_test_interactive_tx_constructor_with_entropy_source(
1587                         TestSession {
1588                                 // We use a deliberately bad entropy source, `DuplicateEntropySource` to simulate this.
1589                                 description: "Attempt to queue up two outputs with duplicate serial ids",
1590                                 inputs_a: vec![],
1591                                 outputs_a: generate_fixed_number_of_outputs(2),
1592                                 inputs_b: vec![],
1593                                 outputs_b: vec![],
1594                                 expect_error: Some((AbortReason::DuplicateSerialId, ErrorCulprit::NodeA)),
1595                         },
1596                         &DuplicateEntropySource,
1597                 );
1598
1599                 do_test_interactive_tx_constructor(TestSession {
1600                         description: "Peer contributed more output value than inputs",
1601                         inputs_a: generate_inputs(&[TestOutput::P2WPKH(100_000)]),
1602                         outputs_a: generate_outputs(&[TestOutput::P2WPKH(1_000_000)]),
1603                         inputs_b: vec![],
1604                         outputs_b: vec![],
1605                         expect_error: Some((AbortReason::OutputsValueExceedsInputsValue, ErrorCulprit::NodeA)),
1606                 });
1607
1608                 do_test_interactive_tx_constructor(TestSession {
1609                         description: "Peer contributed more than allowed number of inputs",
1610                         inputs_a: generate_fixed_number_of_inputs(MAX_INPUTS_OUTPUTS_COUNT as u16 + 1),
1611                         outputs_a: vec![],
1612                         inputs_b: vec![],
1613                         outputs_b: vec![],
1614                         expect_error: Some((
1615                                 AbortReason::ExceededNumberOfInputsOrOutputs,
1616                                 ErrorCulprit::Indeterminate,
1617                         )),
1618                 });
1619                 do_test_interactive_tx_constructor(TestSession {
1620                         description: "Peer contributed more than allowed number of outputs",
1621                         inputs_a: generate_inputs(&[TestOutput::P2WPKH(TOTAL_BITCOIN_SUPPLY_SATOSHIS)]),
1622                         outputs_a: generate_fixed_number_of_outputs(MAX_INPUTS_OUTPUTS_COUNT as u16 + 1),
1623                         inputs_b: vec![],
1624                         outputs_b: vec![],
1625                         expect_error: Some((
1626                                 AbortReason::ExceededNumberOfInputsOrOutputs,
1627                                 ErrorCulprit::Indeterminate,
1628                         )),
1629                 });
1630         }
1631
1632         #[test]
1633         fn test_generate_local_serial_id() {
1634                 let entropy_source = TestEntropySource(AtomicCounter::new());
1635
1636                 // Initiators should have even serial id, non-initiators should have odd serial id.
1637                 assert_eq!(generate_holder_serial_id(&&entropy_source, true) % 2, 0);
1638                 assert_eq!(generate_holder_serial_id(&&entropy_source, false) % 2, 1)
1639         }
1640 }