Extract contributed_{inputs|outputs} iterators
What changed, and why it matters
This commit is a straightforward internal code cleanup in the Lightning Dev Kit's transaction-building code. It replaces a few methods that always built full lists of contributed inputs and outputs with new iterator methods that let callers decide when to build those lists. There is no change to security logic, no bug fix, and no externally visible behavior change.
No security action needed. Treat as a normal refactoring review.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The patch refactors four types in rust-lightning (FundingNegotiationContext, ConstructedTransaction, InteractiveTxSigningSession, InteractiveTxConstructor) to expose contributed_inputs() and contributed_outputs() as lazy iterators. Existing to_contributed_inputs_and_outputs() methods are reimplemented by collecting from these iterators. The change avoids unnecessary allocations when callers only need to filter or inspect the items, such as when producing DiscardFunding events. No protocol logic, validation, or access control is modified.
Changed components
lightning/src/ln/channel.rslightning/src/ln/interactivetxs.rsInspect captured patch +38 / −23
diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs
index fee74aa..905adb1 100644
--- a/lightning/src/ln/channel.rs
+++ b/lightning/src/ln/channel.rs
@@ -6833,11 +6833,16 @@ impl FundingNegotiationContext {
(contributed_inputs, contributed_outputs)
}
+ fn contributed_inputs(&self) -> impl Iterator<Item = bitcoin::OutPoint> + '_ {
+ self.our_funding_inputs.iter().map(|input| input.utxo.outpoint)
+ }
+
+ fn contributed_outputs(&self) -> impl Iterator<Item = &TxOut> + '_ {
+ self.our_funding_outputs.iter()
+ }
+
fn to_contributed_inputs_and_outputs(&self) -> (Vec<bitcoin::OutPoint>, Vec<TxOut>) {
- let contributed_inputs =
- self.our_funding_inputs.iter().map(|input| input.utxo.outpoint).collect();
- let contributed_outputs = self.our_funding_outputs.clone();
- (contributed_inputs, contributed_outputs)
+ (self.contributed_inputs().collect(), self.contributed_outputs().cloned().collect())
}
}
diff --git a/lightning/src/ln/interactivetxs.rs b/lightning/src/ln/interactivetxs.rs
index c5db1bc..7e7a9fb 100644
--- a/lightning/src/ln/interactivetxs.rs
+++ b/lightning/src/ln/interactivetxs.rs
@@ -361,9 +361,8 @@ impl ConstructedTransaction {
NegotiationError { reason, contributed_inputs, contributed_outputs }
}
- fn to_contributed_inputs_and_outputs(&self) -> (Vec<BitcoinOutPoint>, Vec<TxOut>) {
- let contributed_inputs = self
- .tx
+ fn contributed_inputs(&self) -> impl Iterator<Item = BitcoinOutPoint> + '_ {
+ self.tx
.input
.iter()
.zip(self.input_metadata.iter())
@@ -375,20 +374,21 @@ impl ConstructedTransaction {
.unwrap_or(true)
})
.map(|(_, (txin, _))| txin.previous_output)
- .collect();
+ }
- let contributed_outputs = self
- .tx
+ fn contributed_outputs(&self) -> impl Iterator<Item = &TxOut> + '_ {
+ self.tx
.output
.iter()
.zip(self.output_metadata.iter())
.enumerate()
.filter(|(_, (_, output))| output.is_local(self.holder_is_initiator))
.filter(|(index, _)| *index != self.shared_output_index as usize)
- .map(|(_, (txout, _))| txout.clone())
- .collect();
+ .map(|(_, (txout, _))| txout)
+ }
- (contributed_inputs, contributed_outputs)
+ fn to_contributed_inputs_and_outputs(&self) -> (Vec<BitcoinOutPoint>, Vec<TxOut>) {
+ (self.contributed_inputs().collect(), self.contributed_outputs().cloned().collect())
}
fn into_contributed_inputs_and_outputs(self) -> (Vec<BitcoinOutPoint>, Vec<TxOut>) {
@@ -899,8 +899,16 @@ impl InteractiveTxSigningSession {
self.unsigned_tx.into_negotiation_error(reason)
}
+ pub(super) fn contributed_inputs(&self) -> impl Iterator<Item = BitcoinOutPoint> + '_ {
+ self.unsigned_tx.contributed_inputs()
+ }
+
+ pub(super) fn contributed_outputs(&self) -> impl Iterator<Item = &TxOut> + '_ {
+ self.unsigned_tx.contributed_outputs()
+ }
+
pub(super) fn to_contributed_inputs_and_outputs(&self) -> (Vec<BitcoinOutPoint>, Vec<TxOut>) {
- self.unsigned_tx.to_contributed_inputs_and_outputs()
+ (self.contributed_inputs().collect(), self.contributed_outputs().cloned().collect())
}
pub(super) fn into_contributed_inputs_and_outputs(self) -> (Vec<BitcoinOutPoint>, Vec<TxOut>) {
@@ -2149,20 +2157,22 @@ impl InteractiveTxConstructor {
(contributed_inputs, contributed_outputs)
}
- pub(super) fn to_contributed_inputs_and_outputs(&self) -> (Vec<BitcoinOutPoint>, Vec<TxOut>) {
- let contributed_inputs = self
- .inputs_to_contribute
+ pub(super) fn contributed_inputs(&self) -> impl Iterator<Item = BitcoinOutPoint> + '_ {
+ self.inputs_to_contribute
.iter()
.filter(|(_, input)| !input.is_shared())
.map(|(_, input)| input.tx_in().previous_output)
- .collect();
- let contributed_outputs = self
- .outputs_to_contribute
+ }
+
+ pub(super) fn contributed_outputs(&self) -> impl Iterator<Item = &TxOut> + '_ {
+ self.outputs_to_contribute
.iter()
.filter(|(_, output)| !output.is_shared())
- .map(|(_, output)| output.tx_out().clone())
- .collect();
- (contributed_inputs, contributed_outputs)
+ .map(|(_, output)| output.tx_out())
+ }
+
+ pub(super) fn to_contributed_inputs_and_outputs(&self) -> (Vec<BitcoinOutPoint>, Vec<TxOut>) {
+ (self.contributed_inputs().collect(), self.contributed_outputs().cloned().collect())
}
pub fn is_initiator(&self) -> bool {
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.