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