diff --git a/lightning/src/ln/interactivetxs.rs b/lightning/src/ln/interactivetxs.rs index a5c728a012a..c3dc02e7889 100644 --- a/lightning/src/ln/interactivetxs.rs +++ b/lightning/src/ln/interactivetxs.rs @@ -107,7 +107,7 @@ impl NegotiationContext { self.outputs .iter() .filter(move |(serial_id, _)| self.is_serial_id_valid_for_counterparty(serial_id)) - .map(|(_, input_with_prevout)| input_with_prevout) + .map(|(_, output)| output) } fn received_tx_add_input(&mut self, msg: &msgs::TxAddInput) -> Result<(), AbortReason> { @@ -147,7 +147,9 @@ impl NegotiationContext { // - MUST fail the negotiation if: // - the `scriptPubKey` is not a witness program return Err(AbortReason::PrevTxOutInvalid); - } else if !self.prevtx_outpoints.insert(OutPoint { txid, vout: msg.prevtx_out }) { + } + + if !self.prevtx_outpoints.insert(OutPoint { txid, vout: msg.prevtx_out }) { // The receiving node: // - MUST fail the negotiation if: // - the `prevtx` and `prevtx_vout` are identical to a previously added @@ -173,17 +175,14 @@ impl NegotiationContext { return Err(AbortReason::DuplicateSerialId); } let prev_outpoint = OutPoint { txid, vout: msg.prevtx_out }; - self.inputs.insert( - msg.serial_id, - TxInputWithPrevOutput { - input: TxIn { - previous_output: prev_outpoint.clone(), - sequence: Sequence(msg.sequence), - ..Default::default() - }, - prev_output: prev_out, + self.inputs.entry(msg.serial_id).or_insert_with(|| TxInputWithPrevOutput { + input: TxIn { + previous_output: prev_outpoint.clone(), + sequence: Sequence(msg.sequence), + ..Default::default() }, - ); + prev_output: prev_out, + }); self.prevtx_outpoints.insert(prev_outpoint); Ok(()) } @@ -193,15 +192,14 @@ impl NegotiationContext { return Err(AbortReason::IncorrectSerialIdParity); } - if let Some(_) = self.inputs.remove(&msg.serial_id) { - Ok(()) - } else { + self.inputs + .remove(&msg.serial_id) // The receiving node: // - MUST fail the negotiation if: // - the input or output identified by the `serial_id` was not added by the sender // - the `serial_id` does not correspond to a currently added input - Err(AbortReason::SerialIdUnknown) - } + .ok_or(AbortReason::SerialIdUnknown) + .map(|_| ()) } fn received_tx_add_output(&mut self, msg: &msgs::TxAddOutput) -> Result<(), AbortReason> { @@ -226,7 +224,14 @@ impl NegotiationContext { // - the sats amount is less than the dust_limit return Err(AbortReason::BelowDustLimit); } - if msg.sats > TOTAL_BITCOIN_SUPPLY_SATOSHIS { + + // Check that adding this output would not cause the total output value to exceed the total + // bitcoin supply. + let mut outputs_value: u64 = 0; + for output in self.outputs.iter() { + outputs_value = outputs_value.saturating_add(output.1.value); + } + if outputs_value.saturating_add(msg.sats) > TOTAL_BITCOIN_SUPPLY_SATOSHIS { // The receiving node: // - MUST fail the negotiation if: // - the sats amount is greater than 2,100,000,000,000,000 (TOTAL_BITCOIN_SUPPLY_SATOSHIS) @@ -257,7 +262,7 @@ impl NegotiationContext { } let output = TxOut { value: msg.sats, script_pubkey: msg.script.clone() }; - self.outputs.insert(msg.serial_id, output); + self.outputs.entry(msg.serial_id).or_insert(output); Ok(()) }