Add `prev_ouput` to `NegotiatedTxInput` for SIGHASH_ALL & key-spend checks
What changed, and why it matters
This commit adds the previous transaction output (the 'prev_output', which includes the scriptPubKey and amount) to an internal data structure called NegotiatedTxInput used during interactive transaction construction in Lightning. The commit message says a future change will use this extra data to verify that certain Bitcoin spends are valid and that signatures use the SIGHASH_ALL mode, which helps prevent funds from being frozen or held hostage by a malicious peer. By itself, this patch only stores more data; it does not yet implement the actual security checks.
Review the follow-up commit that implements the actual P2WPKH/P2TR key-spend and SIGHASH_ALL checks to confirm the new prev_output field is used correctly and that the security goal is achieved. Treat this commit as groundwork, not as a complete fix.
Security signals we found
Commit message describes preventing funds from being frozen or held ransom via SIGHASH_ALL enforcement
Commit message describes validating P2WPKH and P2TR key-path spends using scriptPubKey data
Adds prev_output (scriptPubKey + value) to an interactive-tx input structure
No actual validation logic is present in this commit; it is preparatory
Evidence from the diff
The patch extends the internal NegotiatedTxInput struct in lightning/src/ln/interactivetxs.rs with a prev_output: TxOut field and updates its TLV serialization. It also adds an InputOwned::into_tx_in_with_prev_output helper and changes InteractiveTxInput::into_negotiated_input to populate the new field. The commit message explicitly frames the change as preparation for validating P2WPKH and P2TR key-path spends and for ensuring holder-witness signatures use SIGHASH_ALL to prevent ransom/freeze attacks. The diff contains no actual validation logic, so this is a preparatory, non-functional change for the security feature described.
Changed components
lightning/src/ln/interactivetxs.rsNegotiatedTxInput structInteractiveTxInput::into_negotiated_inputInputOwned helperInspect captured patch +11 / −1
diff --git a/lightning/src/ln/interactivetxs.rs b/lightning/src/ln/interactivetxs.rs
index 5ed3d5e..66839b6 100644
--- a/lightning/src/ln/interactivetxs.rs
+++ b/lightning/src/ln/interactivetxs.rs
@@ -210,12 +210,14 @@ pub(crate) struct NegotiatedTxInput {
txin: TxIn,
// The weight of the input including an estimate of its witness weight.
weight: Weight,
+ prev_output: TxOut,
}
impl_writeable_tlv_based!(NegotiatedTxInput, {
(1, serial_id, required),
(3, txin, required),
(5, weight, required),
+ (7, prev_output, required),
});
impl_writeable_tlv_based!(ConstructedTransaction, {
@@ -1365,6 +1367,13 @@ impl InputOwned {
InputOwned::Shared(shared) => estimate_input_weight(&shared.prev_output),
}
}
+
+ fn into_tx_in_with_prev_output(self) -> (TxIn, TxOut) {
+ match self {
+ InputOwned::Single(single) => (single.input, single.prev_output),
+ InputOwned::Shared(shared) => (shared.input, shared.prev_output),
+ }
+ }
}
#[derive(Clone, Debug, Eq, PartialEq)]
@@ -1536,7 +1545,8 @@ impl InteractiveTxInput {
fn into_negotiated_input(self) -> NegotiatedTxInput {
let weight = self.input.estimate_input_weight();
- NegotiatedTxInput { serial_id: self.serial_id, txin: self.input.into_tx_in(), weight }
+ let (txin, prev_output) = self.input.into_tx_in_with_prev_output();
+ NegotiatedTxInput { serial_id: self.serial_id, txin, weight, prev_output }
}
}
Why this scored 44/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.