Abort if we add a duplicate input
authorDuncan Dean <git@dunxen.dev>
Tue, 26 Mar 2024 10:15:37 +0000 (12:15 +0200)
committerDuncan Dean <git@dunxen.dev>
Tue, 23 Apr 2024 09:30:00 +0000 (11:30 +0200)
lightning/src/ln/interactivetxs.rs

index 33a8bfc2f7c2f7a54e36dd438fec020a884ef9d4..836258b5893be6e5651f22572b0a3a7ca787da23 100644 (file)
@@ -308,7 +308,10 @@ impl NegotiationContext {
                };
                let prev_output =
                        tx.output.get(msg.prevtx_out as usize).ok_or(AbortReason::PrevTxOutInvalid)?.clone();
-               self.prevtx_outpoints.insert(input.previous_output);
+               if !self.prevtx_outpoints.insert(input.previous_output) {
+                       // We have added an input that already exists
+                       return Err(AbortReason::PrevTxOutInvalid);
+               }
                self.inputs.insert(msg.serial_id, TxInputWithPrevOutput { input, prev_output });
                Ok(())
        }
@@ -1253,7 +1256,7 @@ mod tests {
                        outputs_a: generate_outputs(&[1_000_000]),
                        inputs_b: vec![],
                        outputs_b: vec![],
-                       expect_error: Some((AbortReason::PrevTxOutInvalid, ErrorCulprit::NodeA)),
+                       expect_error: Some((AbortReason::PrevTxOutInvalid, ErrorCulprit::NodeB)),
                });
                // Non-initiator uses same prevout as initiator.
                let duplicate_input = TxIn {
@@ -1266,7 +1269,7 @@ mod tests {
                        outputs_a: generate_outputs(&[1_000_000]),
                        inputs_b: vec![(duplicate_input.clone(), tx.clone())],
                        outputs_b: vec![],
-                       expect_error: Some((AbortReason::PrevTxOutInvalid, ErrorCulprit::NodeB)),
+                       expect_error: Some((AbortReason::PrevTxOutInvalid, ErrorCulprit::NodeA)),
                });
                // Initiator sends too many TxAddInputs
                do_test_interactive_tx_constructor(TestSession {