Skip to content

Commit

Permalink
f ensure we validate total output amount against max bitcoin supply
Browse files Browse the repository at this point in the history
  • Loading branch information
jurvis authored and dunxen committed Mar 5, 2024
1 parent 708948d commit f08c112
Showing 1 changed file with 24 additions and 19 deletions.
43 changes: 24 additions & 19 deletions lightning/src/ln/interactivetxs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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> {
Expand Down Expand Up @@ -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
Expand All @@ -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(())
}
Expand All @@ -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> {
Expand All @@ -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)
Expand All @@ -252,7 +257,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(())
}

Expand Down

0 comments on commit f08c112

Please sign in to comment.