Skip to content

Commit f8cf343

Browse files
committed
Force-close channels on underflow.
1 parent 13835c0 commit f8cf343

File tree

1 file changed

+12
-6
lines changed

1 file changed

+12
-6
lines changed

lightning/src/ln/channel.rs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4351,7 +4351,7 @@ impl<SP: Deref> Channel<SP> where
43514351
}
43524352

43534353
#[inline]
4354-
fn build_closing_transaction(&self, proposed_total_fee_satoshis: u64, skip_remote_output: bool) -> (ClosingTransaction, u64) {
4354+
fn build_closing_transaction(&self, proposed_total_fee_satoshis: u64, skip_remote_output: bool) -> Result<(ClosingTransaction, u64), ChannelError> {
43554355
assert!(self.context.pending_inbound_htlcs.is_empty());
43564356
assert!(self.context.pending_outbound_htlcs.is_empty());
43574357
assert!(self.context.pending_update_fee.is_none());
@@ -4369,11 +4369,17 @@ impl<SP: Deref> Channel<SP> where
43694369
}
43704370

43714371
debug_assert!(value_to_counterparty >= 0);
4372+
if value_to_counterparty < 0 {
4373+
return Err(ChannelError::close(format!("Value to counterparty below 0: {}", value_to_counterparty)))
4374+
}
43724375
if skip_remote_output || value_to_counterparty as u64 <= self.context.holder_dust_limit_satoshis {
43734376
value_to_counterparty = 0;
43744377
}
43754378

43764379
debug_assert!(value_to_holder >= 0);
4380+
if value_to_holder < 0 {
4381+
return Err(ChannelError::close(format!("Value to holder below 0: {}", value_to_holder)))
4382+
}
43774383
if value_to_holder as u64 <= self.context.holder_dust_limit_satoshis {
43784384
value_to_holder = 0;
43794385
}
@@ -4384,7 +4390,7 @@ impl<SP: Deref> Channel<SP> where
43844390
let funding_outpoint = self.funding_outpoint().into_bitcoin_outpoint();
43854391

43864392
let closing_transaction = ClosingTransaction::new(value_to_holder as u64, value_to_counterparty as u64, holder_shutdown_script, counterparty_shutdown_script, funding_outpoint);
4387-
(closing_transaction, total_fee_satoshis)
4393+
Ok((closing_transaction, total_fee_satoshis))
43884394
}
43894395

43904396
fn funding_outpoint(&self) -> OutPoint {
@@ -6618,7 +6624,7 @@ impl<SP: Deref> Channel<SP> where
66186624
let (our_min_fee, our_max_fee) = self.calculate_closing_fee_limits(fee_estimator);
66196625

66206626
assert!(self.context.shutdown_scriptpubkey.is_some());
6621-
let (closing_tx, total_fee_satoshis) = self.build_closing_transaction(our_min_fee, false);
6627+
let (closing_tx, total_fee_satoshis) = self.build_closing_transaction(our_min_fee, false)?;
66226628
log_trace!(logger, "Proposing initial closing_signed for our counterparty with a fee range of {}-{} sat (with initial proposal {} sats)",
66236629
our_min_fee, our_max_fee, total_fee_satoshis);
66246630

@@ -6852,7 +6858,7 @@ impl<SP: Deref> Channel<SP> where
68526858

68536859
let funding_redeemscript = self.context.get_funding_redeemscript();
68546860
let mut skip_remote_output = false;
6855-
let (mut closing_tx, used_total_fee) = self.build_closing_transaction(msg.fee_satoshis, skip_remote_output);
6861+
let (mut closing_tx, used_total_fee) = self.build_closing_transaction(msg.fee_satoshis, skip_remote_output)?;
68566862
if used_total_fee != msg.fee_satoshis {
68576863
return Err(ChannelError::close(format!("Remote sent us a closing_signed with a fee other than the value they can claim. Fee in message: {}. Actual closing tx fee: {}", msg.fee_satoshis, used_total_fee)));
68586864
}
@@ -6864,7 +6870,7 @@ impl<SP: Deref> Channel<SP> where
68646870
// The remote end may have decided to revoke their output due to inconsistent dust
68656871
// limits, so check for that case by re-checking the signature here.
68666872
skip_remote_output = true;
6867-
closing_tx = self.build_closing_transaction(msg.fee_satoshis, skip_remote_output).0;
6873+
closing_tx = self.build_closing_transaction(msg.fee_satoshis, skip_remote_output)?.0;
68686874
let sighash = closing_tx.trust().get_sighash_all(&funding_redeemscript, self.context.channel_value_satoshis);
68696875
secp_check!(self.context.secp_ctx.verify_ecdsa(&sighash, &msg.signature, self.context.counterparty_funding_pubkey()), "Invalid closing tx signature from peer".to_owned());
68706876
},
@@ -6895,7 +6901,7 @@ impl<SP: Deref> Channel<SP> where
68956901
(closing_tx, $new_fee)
68966902
} else {
68976903
skip_remote_output = false;
6898-
self.build_closing_transaction($new_fee, skip_remote_output)
6904+
self.build_closing_transaction($new_fee, skip_remote_output)?
68996905
};
69006906

69016907
let closing_signed = self.get_closing_signed_msg(&closing_tx, skip_remote_output, used_fee, our_min_fee, our_max_fee, logger);

0 commit comments

Comments
 (0)