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