Skip to content

Commit 8ca05a8

Browse files
committed
Keep InteractiveTxConstructor contributed inputs and outputs
Instead of popping each input and output to contribute during an interactive tx session, clone the necessary parts and keep around the original inputs and outputs. This will let us reuse them later when constructing an error. The tradeoff is using additional memory to avoid more code complexity required to extract the sent input and outputs from NegotiationContext.
1 parent 89e1f33 commit 8ca05a8

File tree

1 file changed

+41
-10
lines changed

1 file changed

+41
-10
lines changed

lightning/src/ln/interactivetxs.rs

Lines changed: 41 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1827,6 +1827,8 @@ pub(super) struct InteractiveTxConstructor {
18271827
channel_id: ChannelId,
18281828
inputs_to_contribute: Vec<(SerialId, InputOwned)>,
18291829
outputs_to_contribute: Vec<(SerialId, OutputOwned)>,
1830+
next_input_index: Option<usize>,
1831+
next_output_index: Option<usize>,
18301832
}
18311833

18321834
#[allow(clippy::enum_variant_names)] // Clippy doesn't like the repeated `Tx` prefix here
@@ -1979,12 +1981,17 @@ impl InteractiveTxConstructor {
19791981
// In the same manner and for the same rationale as the inputs above, we'll shuffle the outputs.
19801982
outputs_to_contribute.sort_unstable_by_key(|(serial_id, _)| *serial_id);
19811983

1984+
let next_input_index = (!inputs_to_contribute.is_empty()).then_some(0);
1985+
let next_output_index = (!outputs_to_contribute.is_empty()).then_some(0);
1986+
19821987
let mut constructor = Self {
19831988
state_machine,
19841989
initiator_first_message: None,
19851990
channel_id,
19861991
inputs_to_contribute,
19871992
outputs_to_contribute,
1993+
next_input_index,
1994+
next_output_index,
19881995
};
19891996
// We'll store the first message for the initiator.
19901997
if is_initiator {
@@ -1998,22 +2005,24 @@ impl InteractiveTxConstructor {
19982005
}
19992006

20002007
fn maybe_send_message(&mut self) -> Result<InteractiveTxMessageSend, AbortReason> {
2008+
let channel_id = self.channel_id;
2009+
20012010
// We first attempt to send inputs we want to add, then outputs. Once we are done sending
20022011
// them both, then we always send tx_complete.
2003-
if let Some((serial_id, input)) = self.inputs_to_contribute.pop() {
2012+
if let Some((serial_id, input)) = self.next_input_to_contribute() {
20042013
let satisfaction_weight = input.satisfaction_weight();
20052014
let msg = match input {
20062015
InputOwned::Single(single) => msgs::TxAddInput {
2007-
channel_id: self.channel_id,
2008-
serial_id,
2009-
prevtx: Some(single.prev_tx),
2016+
channel_id,
2017+
serial_id: *serial_id,
2018+
prevtx: Some(single.prev_tx.clone()),
20102019
prevtx_out: single.input.previous_output.vout,
20112020
sequence: single.input.sequence.to_consensus_u32(),
20122021
shared_input_txid: None,
20132022
},
20142023
InputOwned::Shared(shared) => msgs::TxAddInput {
2015-
channel_id: self.channel_id,
2016-
serial_id,
2024+
channel_id,
2025+
serial_id: *serial_id,
20172026
prevtx: None,
20182027
prevtx_out: shared.input.previous_output.vout,
20192028
sequence: shared.input.sequence.to_consensus_u32(),
@@ -2022,22 +2031,44 @@ impl InteractiveTxConstructor {
20222031
};
20232032
do_state_transition!(self, sent_tx_add_input, (&msg, satisfaction_weight))?;
20242033
Ok(InteractiveTxMessageSend::TxAddInput(msg))
2025-
} else if let Some((serial_id, output)) = self.outputs_to_contribute.pop() {
2034+
} else if let Some((serial_id, output)) = self.next_output_to_contribute() {
20262035
let msg = msgs::TxAddOutput {
2027-
channel_id: self.channel_id,
2028-
serial_id,
2036+
channel_id,
2037+
serial_id: *serial_id,
20292038
sats: output.tx_out().value.to_sat(),
20302039
script: output.tx_out().script_pubkey.clone(),
20312040
};
20322041
do_state_transition!(self, sent_tx_add_output, &msg)?;
20332042
Ok(InteractiveTxMessageSend::TxAddOutput(msg))
20342043
} else {
2035-
let msg = msgs::TxComplete { channel_id: self.channel_id };
2044+
let msg = msgs::TxComplete { channel_id };
20362045
do_state_transition!(self, sent_tx_complete, &msg)?;
20372046
Ok(InteractiveTxMessageSend::TxComplete(msg))
20382047
}
20392048
}
20402049

2050+
fn next_input_to_contribute(&mut self) -> Option<&(SerialId, InputOwned)> {
2051+
match self.next_input_index {
2052+
Some(index) => {
2053+
self.next_input_index =
2054+
index.checked_add(1).filter(|index| *index < self.inputs_to_contribute.len());
2055+
self.inputs_to_contribute.get(index)
2056+
},
2057+
None => None,
2058+
}
2059+
}
2060+
2061+
fn next_output_to_contribute(&mut self) -> Option<&(SerialId, OutputOwned)> {
2062+
match self.next_output_index {
2063+
Some(index) => {
2064+
self.next_output_index =
2065+
index.checked_add(1).filter(|index| *index < self.outputs_to_contribute.len());
2066+
self.outputs_to_contribute.get(index)
2067+
},
2068+
None => None,
2069+
}
2070+
}
2071+
20412072
pub fn handle_tx_add_input(
20422073
&mut self, msg: &msgs::TxAddInput,
20432074
) -> Result<InteractiveTxMessageSend, AbortReason> {

0 commit comments

Comments
 (0)