Skip to content

Commit 9eeaf52

Browse files
committed
Remove duplicate TxOut persistence
Now that ConstructedTransaction holds the actual Transaction, there's no need to keep track of and persist the outputs separately. However, the serial IDs are still needed to later reconstruct which outputs were contributed.
1 parent e262326 commit 9eeaf52

File tree

3 files changed

+37
-39
lines changed

3 files changed

+37
-39
lines changed

lightning/src/ln/channel.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6108,8 +6108,8 @@ where
61086108
{
61096109
let mut output_index = None;
61106110
let expected_spk = funding.get_funding_redeemscript().to_p2wsh();
6111-
for (idx, outp) in signing_session.unsigned_tx().outputs().enumerate() {
6112-
if outp.script_pubkey() == &expected_spk && outp.value() == funding.get_value_satoshis() {
6111+
for (idx, outp) in signing_session.unsigned_tx().tx().output.iter().enumerate() {
6112+
if outp.script_pubkey == expected_spk && outp.value.to_sat() == funding.get_value_satoshis() {
61136113
if output_index.is_some() {
61146114
return Err(AbortReason::DuplicateFundingOutput);
61156115
}

lightning/src/ln/interactivetxs.rs

Lines changed: 33 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ pub(crate) struct ConstructedTransaction {
199199
holder_is_initiator: bool,
200200

201201
inputs: Vec<NegotiatedTxInput>,
202-
outputs: Vec<InteractiveTxOutput>,
202+
outputs: Vec<NegotiatedTxOutput>,
203203
tx: Transaction,
204204

205205
local_inputs_value_satoshis: u64,
@@ -217,6 +217,11 @@ pub(crate) struct NegotiatedTxInput {
217217
prev_output: TxOut,
218218
}
219219

220+
#[derive(Clone, Debug, Eq, PartialEq)]
221+
pub(crate) struct NegotiatedTxOutput {
222+
serial_id: SerialId,
223+
}
224+
220225
impl NegotiatedTxInput {
221226
pub(super) fn is_local(&self, holder_is_initiator: bool) -> bool {
222227
!is_serial_id_valid_for_counterparty(holder_is_initiator, self.serial_id)
@@ -227,11 +232,21 @@ impl NegotiatedTxInput {
227232
}
228233
}
229234

235+
impl NegotiatedTxOutput {
236+
pub(super) fn is_local(&self, holder_is_initiator: bool) -> bool {
237+
!is_serial_id_valid_for_counterparty(holder_is_initiator, self.serial_id)
238+
}
239+
}
240+
230241
impl_writeable_tlv_based!(NegotiatedTxInput, {
231242
(1, serial_id, required),
232243
(3, prev_output, required),
233244
});
234245

246+
impl_writeable_tlv_based!(NegotiatedTxOutput, {
247+
(1, serial_id, required),
248+
});
249+
235250
impl_writeable_tlv_based!(ConstructedTransaction, {
236251
(1, holder_is_initiator, required),
237252
(3, inputs, required),
@@ -284,9 +299,13 @@ impl ConstructedTransaction {
284299
.into_values()
285300
.map(|input| input.into_txin_and_negotiated_input())
286301
.collect();
287-
let mut outputs: Vec<InteractiveTxOutput> = context.outputs.into_values().collect();
302+
let mut outputs: Vec<(TxOut, NegotiatedTxOutput)> = context
303+
.outputs
304+
.into_values()
305+
.map(|output| output.into_txout_and_negotiated_output())
306+
.collect();
288307
inputs.sort_unstable_by_key(|(_, input)| input.serial_id);
289-
outputs.sort_unstable_by_key(|output| output.serial_id);
308+
outputs.sort_unstable_by_key(|(_, output)| output.serial_id);
290309

291310
let shared_input_index =
292311
context.shared_funding_input.as_ref().and_then(|shared_funding_input| {
@@ -299,7 +318,7 @@ impl ConstructedTransaction {
299318
});
300319

301320
let (input, inputs): (Vec<TxIn>, Vec<NegotiatedTxInput>) = inputs.into_iter().unzip();
302-
let output = outputs.iter().map(|output| output.tx_out().clone()).collect();
321+
let (output, outputs): (Vec<TxOut>, Vec<NegotiatedTxOutput>) = outputs.into_iter().unzip();
303322

304323
let tx =
305324
Transaction { version: Version::TWO, lock_time: context.tx_locktime, input, output };
@@ -330,10 +349,6 @@ impl ConstructedTransaction {
330349
&self.tx
331350
}
332351

333-
pub fn outputs(&self) -> impl Iterator<Item = &InteractiveTxOutput> {
334-
self.outputs.iter()
335-
}
336-
337352
pub fn inputs(&self) -> impl Iterator<Item = &NegotiatedTxInput> {
338353
self.inputs.iter()
339354
}
@@ -565,12 +580,7 @@ impl InteractiveTxSigningSession {
565580
.outputs
566581
.iter()
567582
.enumerate()
568-
.filter(|(_, output)| {
569-
!is_serial_id_valid_for_counterparty(
570-
self.unsigned_tx.holder_is_initiator,
571-
output.serial_id,
572-
)
573-
})
583+
.filter(|(_, output)| output.is_local(self.unsigned_tx.holder_is_initiator))
574584
.count()
575585
}
576586

@@ -1774,12 +1784,6 @@ pub(crate) struct InteractiveTxOutput {
17741784
output: OutputOwned,
17751785
}
17761786

1777-
impl_writeable_tlv_based!(InteractiveTxOutput, {
1778-
(1, serial_id, required),
1779-
(3, added_by, required),
1780-
(5, output, required),
1781-
});
1782-
17831787
impl InteractiveTxOutput {
17841788
pub fn tx_out(&self) -> &TxOut {
17851789
self.output.tx_out()
@@ -1804,6 +1808,11 @@ impl InteractiveTxOutput {
18041808
pub fn script_pubkey(&self) -> &ScriptBuf {
18051809
&self.output.tx_out().script_pubkey
18061810
}
1811+
1812+
fn into_txout_and_negotiated_output(self) -> (TxOut, NegotiatedTxOutput) {
1813+
let txout = self.output.into_tx_out();
1814+
(txout, NegotiatedTxOutput { serial_id: self.serial_id })
1815+
}
18071816
}
18081817

18091818
impl InteractiveTxInput {
@@ -2227,9 +2236,9 @@ mod tests {
22272236
use core::ops::Deref;
22282237

22292238
use super::{
2230-
get_output_weight, AddingRole, ConstructedTransaction, InteractiveTxOutput,
2231-
InteractiveTxSigningSession, NegotiatedTxInput, OutputOwned, P2TR_INPUT_WEIGHT_LOWER_BOUND,
2232-
P2WPKH_INPUT_WEIGHT_LOWER_BOUND, P2WSH_INPUT_WEIGHT_LOWER_BOUND, TX_COMMON_FIELDS_WEIGHT,
2239+
get_output_weight, ConstructedTransaction, InteractiveTxSigningSession, NegotiatedTxInput,
2240+
P2TR_INPUT_WEIGHT_LOWER_BOUND, P2WPKH_INPUT_WEIGHT_LOWER_BOUND,
2241+
P2WSH_INPUT_WEIGHT_LOWER_BOUND, TX_COMMON_FIELDS_WEIGHT,
22332242
};
22342243

22352244
const TEST_FEERATE_SATS_PER_KW: u32 = FEERATE_FLOOR_SATS_PER_KW * 10;
@@ -3312,21 +3321,10 @@ mod tests {
33123321
})
33133322
.collect();
33143323

3315-
let outputs: Vec<InteractiveTxOutput> = transaction
3316-
.output
3317-
.iter()
3318-
.cloned()
3319-
.map(|txout| InteractiveTxOutput {
3320-
serial_id: 0, // N/A for test
3321-
added_by: AddingRole::Local,
3322-
output: OutputOwned::Single(txout),
3323-
})
3324-
.collect();
3325-
33263324
let unsigned_tx = ConstructedTransaction {
33273325
holder_is_initiator: true,
33283326
inputs,
3329-
outputs,
3327+
outputs: vec![], // N/A for test
33303328
tx: transaction.clone(),
33313329
local_inputs_value_satoshis: 0, // N/A for test
33323330
local_outputs_value_satoshis: 0, // N/A for test

lightning/src/util/ser.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
1616
use crate::io::{self, BufRead, Read, Write};
1717
use crate::io_extras::{copy, sink};
18-
use crate::ln::interactivetxs::{InteractiveTxOutput, NegotiatedTxInput};
18+
use crate::ln::interactivetxs::{NegotiatedTxInput, NegotiatedTxOutput};
1919
use crate::ln::onion_utils::{HMAC_COUNT, HMAC_LEN, HOLD_TIME_LEN, MAX_HOPS};
2020
use crate::prelude::*;
2121
use crate::sync::{Mutex, RwLock};
@@ -1083,7 +1083,7 @@ impl_for_vec!(crate::ln::msgs::SocketAddress);
10831083
impl_for_vec!((A, B), A, B);
10841084
impl_for_vec!(SerialId);
10851085
impl_for_vec!(NegotiatedTxInput);
1086-
impl_for_vec!(InteractiveTxOutput);
1086+
impl_for_vec!(NegotiatedTxOutput);
10871087
impl_for_vec!(crate::ln::our_peer_storage::PeerStorageMonitorHolder);
10881088
impl_for_vec!(crate::blinded_path::message::BlindedMessagePath);
10891089
impl_writeable_for_vec!(&crate::routing::router::BlindedTail);

0 commit comments

Comments
 (0)