Skip to content

Commit 86777ee

Browse files
jurvisdunxen
authored andcommitted
f ensure we validate total output amount against max bitcoin supply
1 parent 2125c9b commit 86777ee

File tree

1 file changed

+24
-19
lines changed

1 file changed

+24
-19
lines changed

lightning/src/ln/interactivetxs.rs

+24-19
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ impl NegotiationContext {
107107
self.outputs
108108
.iter()
109109
.filter(move |(serial_id, _)| self.is_serial_id_valid_for_counterparty(serial_id))
110-
.map(|(_, input_with_prevout)| input_with_prevout)
110+
.map(|(_, output)| output)
111111
}
112112

113113
fn received_tx_add_input(&mut self, msg: &msgs::TxAddInput) -> Result<(), AbortReason> {
@@ -147,7 +147,9 @@ impl NegotiationContext {
147147
// - MUST fail the negotiation if:
148148
// - the `scriptPubKey` is not a witness program
149149
return Err(AbortReason::PrevTxOutInvalid);
150-
} else if !self.prevtx_outpoints.insert(OutPoint { txid, vout: msg.prevtx_out }) {
150+
}
151+
152+
if !self.prevtx_outpoints.insert(OutPoint { txid, vout: msg.prevtx_out }) {
151153
// The receiving node:
152154
// - MUST fail the negotiation if:
153155
// - the `prevtx` and `prevtx_vout` are identical to a previously added
@@ -173,17 +175,14 @@ impl NegotiationContext {
173175
return Err(AbortReason::DuplicateSerialId);
174176
}
175177
let prev_outpoint = OutPoint { txid, vout: msg.prevtx_out };
176-
self.inputs.insert(
177-
msg.serial_id,
178-
TxInputWithPrevOutput {
179-
input: TxIn {
180-
previous_output: prev_outpoint.clone(),
181-
sequence: Sequence(msg.sequence),
182-
..Default::default()
183-
},
184-
prev_output: prev_out,
178+
self.inputs.entry(msg.serial_id).or_insert_with(|| TxInputWithPrevOutput {
179+
input: TxIn {
180+
previous_output: prev_outpoint.clone(),
181+
sequence: Sequence(msg.sequence),
182+
..Default::default()
185183
},
186-
);
184+
prev_output: prev_out,
185+
});
187186
self.prevtx_outpoints.insert(prev_outpoint);
188187
Ok(())
189188
}
@@ -193,15 +192,14 @@ impl NegotiationContext {
193192
return Err(AbortReason::IncorrectSerialIdParity);
194193
}
195194

196-
if let Some(_) = self.inputs.remove(&msg.serial_id) {
197-
Ok(())
198-
} else {
195+
self.inputs
196+
.remove(&msg.serial_id)
199197
// The receiving node:
200198
// - MUST fail the negotiation if:
201199
// - the input or output identified by the `serial_id` was not added by the sender
202200
// - the `serial_id` does not correspond to a currently added input
203-
Err(AbortReason::SerialIdUnknown)
204-
}
201+
.ok_or(AbortReason::SerialIdUnknown)
202+
.map(|_| ())
205203
}
206204

207205
fn received_tx_add_output(&mut self, msg: &msgs::TxAddOutput) -> Result<(), AbortReason> {
@@ -226,7 +224,14 @@ impl NegotiationContext {
226224
// - the sats amount is less than the dust_limit
227225
return Err(AbortReason::BelowDustLimit);
228226
}
229-
if msg.sats > TOTAL_BITCOIN_SUPPLY_SATOSHIS {
227+
228+
// Check that adding this output would not cause the total output value to exceed the total
229+
// bitcoin supply.
230+
let mut outputs_value: u64 = 0;
231+
for output in self.outputs.iter() {
232+
outputs_value = outputs_value.saturating_add(output.1.value);
233+
}
234+
if outputs_value.saturating_add(msg.sats) > TOTAL_BITCOIN_SUPPLY_SATOSHIS {
230235
// The receiving node:
231236
// - MUST fail the negotiation if:
232237
// - the sats amount is greater than 2,100,000,000,000,000 (TOTAL_BITCOIN_SUPPLY_SATOSHIS)
@@ -257,7 +262,7 @@ impl NegotiationContext {
257262
}
258263

259264
let output = TxOut { value: msg.sats, script_pubkey: msg.script.clone() };
260-
self.outputs.insert(msg.serial_id, output);
265+
self.outputs.entry(msg.serial_id).or_insert(output);
261266
Ok(())
262267
}
263268

0 commit comments

Comments
 (0)