Skip to content

Commit 562a111

Browse files
committed
Review comments: reserve check, etc
1 parent 7683c1d commit 562a111

File tree

2 files changed

+45
-28
lines changed

2 files changed

+45
-28
lines changed

lightning/src/ln/channel.rs

+28-16
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@ use bitcoin::secp256k1::constants::PUBLIC_KEY_SIZE;
2323
use bitcoin::secp256k1::{PublicKey,SecretKey};
2424
use bitcoin::secp256k1::{Secp256k1,ecdsa::Signature};
2525
use bitcoin::{secp256k1, sighash};
26-
#[cfg(splicing)]
27-
use bitcoin::TxIn;
2826

2927
use crate::ln::types::ChannelId;
3028
use crate::types::payment::{PaymentPreimage, PaymentHash};
@@ -1185,11 +1183,12 @@ impl UnfundedChannelContext {
11851183
#[derive(Clone)]
11861184
pub(crate) struct PendingSpliceInfoPre {
11871185
pub our_funding_contribution: i64,
1188-
pub funding_feerate_perkw: u32,
1189-
pub locktime: u32,
1190-
/// The funding inputs we will be contributing to the splice.
1191-
/// TODO(splice): will be changed to TransactionU16LenLimited
1192-
pub our_funding_inputs: Vec<(TxIn, Transaction)>,
1186+
// TODO(splicing): Enable below fields
1187+
// pub funding_feerate_perkw: u32,
1188+
// pub locktime: u32,
1189+
// /// The funding inputs we will be contributing to the splice.
1190+
// /// TODO(splice): will be changed to TransactionU16LenLimited
1191+
// pub our_funding_inputs: Vec<(TxIn, Transaction)>,
11931192
}
11941193

11951194
#[cfg(splicing)]
@@ -3425,6 +3424,27 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
34253424
(context.holder_selected_channel_reserve_satoshis, context.counterparty_selected_channel_reserve_satoshis)
34263425
}
34273426

3427+
/// Check that a proposed channel value meets the channel reserve requirements or violates them (below reserve)
3428+
pub fn check_channel_value_meets_reserve_requirements(&self, proposed_channel_value: u64) -> Result<(), ChannelError> {
3429+
let holder_selected_channel_reserve_satoshis = get_v2_channel_reserve_satoshis(
3430+
proposed_channel_value, self.holder_dust_limit_satoshis);
3431+
if proposed_channel_value < holder_selected_channel_reserve_satoshis {
3432+
return Err(ChannelError::Warn(format!(
3433+
"Proposed channel value below reserve mandated by holder, {} vs {}",
3434+
proposed_channel_value, holder_selected_channel_reserve_satoshis,
3435+
)));
3436+
}
3437+
let counterparty_selected_channel_reserve_satoshis = get_v2_channel_reserve_satoshis(
3438+
proposed_channel_value, self.counterparty_dust_limit_satoshis);
3439+
if proposed_channel_value < counterparty_selected_channel_reserve_satoshis {
3440+
return Err(ChannelError::Warn(format!(
3441+
"Proposed channel value below reserve mandated by counterparty, {} vs {}",
3442+
proposed_channel_value, counterparty_selected_channel_reserve_satoshis,
3443+
)));
3444+
}
3445+
Ok(())
3446+
}
3447+
34283448
/// Get the commitment tx fee for the local's (i.e. our) next commitment transaction based on the
34293449
/// number of pending HTLCs that are on track to be in our next commitment tx.
34303450
///
@@ -3828,10 +3848,6 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
38283848
pub fn get_splice_init(&self, our_funding_contribution_satoshis: i64, signer_provider: &SP,
38293849
funding_feerate_perkw: u32, locktime: u32,
38303850
) -> msgs::SpliceInit {
3831-
if !self.is_outbound() {
3832-
panic!("Tried to initiate a splice on an inbound channel!");
3833-
}
3834-
38353851
// At this point we are not committed to the new channel value yet, but the funding pubkey
38363852
// depends on the channel value, so we create here a new funding pubkey with the new
38373853
// channel value.
@@ -3861,10 +3877,6 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
38613877
/// Get the splice_ack message that can be sent in response to splice initiation.
38623878
#[cfg(splicing)]
38633879
pub fn get_splice_ack(&mut self, our_funding_contribution_satoshis: i64) -> Result<msgs::SpliceAck, ChannelError> {
3864-
if self.is_outbound() {
3865-
panic!("Tried to accept a splice on an outound channel!");
3866-
}
3867-
38683880
// TODO(splicing): checks
38693881

38703882
// Note: at this point keys are already updated
@@ -7458,7 +7470,7 @@ impl<SP: Deref> Channel<SP> where
74587470
#[cfg(splicing)]
74597471
pub fn splice_init<ES: Deref, L: Deref>(
74607472
&mut self, our_funding_contribution_satoshis: i64,
7461-
_signer_provider: &SP, _entropy_source: &ES, _holder_node_id: PublicKey, logger: &L
7473+
_signer_provider: &SP, _entropy_source: &ES, _holder_node_id: PublicKey, _logger: &L
74627474
)
74637475
-> Result<msgs::SpliceAck, ChannelError>
74647476
where ES::Target: EntropySource, L::Target: Logger

lightning/src/ln/channelmanager.rs

+17-12
Original file line numberDiff line numberDiff line change
@@ -4011,7 +4011,7 @@ where
40114011
#[cfg(splicing)]
40124012
pub fn splice_channel(
40134013
&self, channel_id: &ChannelId, counterparty_node_id: &PublicKey, our_funding_contribution_satoshis: i64,
4014-
our_funding_inputs: Vec<(TxIn, Transaction)>, funding_feerate_perkw: u32, locktime: u32,
4014+
_our_funding_inputs: Vec<(TxIn, Transaction)>, funding_feerate_perkw: u32, locktime: u32,
40154015
) -> Result<(), APIError> {
40164016
let per_peer_state = self.per_peer_state.read().unwrap();
40174017

@@ -4027,7 +4027,7 @@ where
40274027
if let ChannelPhase::Funded(chan) = chan_phase_entry.get_mut() {
40284028
let pre_channel_value = chan.context.get_value_satoshis();
40294029
// Sanity check: capacity cannot decrease below 0
4030-
if our_funding_contribution_satoshis < 0 && -our_funding_contribution_satoshis > (pre_channel_value as i64) {
4030+
if (pre_channel_value as i64).saturating_add(our_funding_contribution_satoshis) < 0 {
40314031
return Err(APIError::APIMisuseError {
40324032
err: format!(
40334033
"Post-splicing channel value cannot be negative. It was {} - {}",
@@ -4054,7 +4054,6 @@ where
40544054

40554055
chan.context.pending_splice_pre = Some(PendingSpliceInfoPre {
40564056
our_funding_contribution: our_funding_contribution_satoshis,
4057-
funding_feerate_perkw, locktime, our_funding_inputs,
40584057
});
40594058

40604059
let msg = chan.context.get_splice_init(our_funding_contribution_satoshis, &self.signer_provider, funding_feerate_perkw, locktime);
@@ -9013,7 +9012,7 @@ where
90139012
if let ChannelPhase::Funded(chan) = chan_entry.get_mut() {
90149013
let pre_channel_value = chan.context.get_value_satoshis();
90159014
// Sanity check: capacity cannot decrease below 0
9016-
if msg.funding_contribution_satoshis < 0 && -msg.funding_contribution_satoshis > (pre_channel_value as i64) {
9015+
if (pre_channel_value as i64).saturating_add(msg.funding_contribution_satoshis) < 0 {
90179016
return Err(MsgHandleErrInternal::send_err_msg_no_close(format!(
90189017
"Post-splicing channel value cannot be negative. It was {} - {}", pre_channel_value, -msg.funding_contribution_satoshis,
90199018
), msg.channel_id));
@@ -9026,11 +9025,10 @@ where
90269025
}
90279026

90289027
let post_channel_value = PendingSpliceInfoPre::compute_post_value(pre_channel_value, msg.funding_contribution_satoshis, our_funding_contribution);
9029-
if post_channel_value < 1000 {
9030-
return Err(MsgHandleErrInternal::send_err_msg_no_close(format!(
9031-
"Post-splicing channel value must be at least 1000 satoshis. It was {}", post_channel_value,
9032-
), msg.channel_id));
9033-
}
9028+
9029+
// Check for reserve requirement, it will also be checked later at tx_complete
9030+
let _res = chan.context.check_channel_value_meets_reserve_requirements(post_channel_value)
9031+
.map_err(|e| MsgHandleErrInternal::from_chan_no_close(e, msg.channel_id))?;
90349032

90359033
// Check if a splice has been initiated already.
90369034
// Note: this could be handled more nicely, and support multiple outstanding splice's, the incoming splice_ack matters anyways.
@@ -9083,20 +9081,27 @@ where
90839081
let peer_state = &mut *peer_state_lock;
90849082

90859083
// Look for the channel
9086-
let _pending_splice = match peer_state.channel_by_id.entry(msg.channel_id) {
9084+
match peer_state.channel_by_id.entry(msg.channel_id) {
90879085
hash_map::Entry::Vacant(_) => return Err(MsgHandleErrInternal::send_err_msg_no_close(format!(
90889086
"Got a message for a channel from the wrong node! No such channel for the passed counterparty_node_id {}",
90899087
counterparty_node_id
90909088
), msg.channel_id)),
90919089
hash_map::Entry::Occupied(mut chan) => {
90929090
if let ChannelPhase::Funded(chan) = chan.get_mut() {
90939091
// check if splice is pending
9094-
if let Some(pending_splice) = &chan.context.pending_splice_pre {
9092+
let pending_splice = if let Some(pending_splice) = &chan.context.pending_splice_pre {
90959093
// Note: this is incomplete (their funding contribution is not set)
90969094
pending_splice.clone()
90979095
} else {
90989096
return Err(MsgHandleErrInternal::send_err_msg_no_close("Channel is not in pending splice".to_owned(), msg.channel_id));
9099-
}
9097+
};
9098+
9099+
let pre_channel_value = chan.context.get_value_satoshis();
9100+
let post_channel_value = PendingSpliceInfoPre::compute_post_value(pre_channel_value, pending_splice.our_funding_contribution, msg.funding_contribution_satoshis);
9101+
9102+
// Check for reserve requirement, it will also be checked later at tx_complete
9103+
let _res = chan.context.check_channel_value_meets_reserve_requirements(post_channel_value)
9104+
.map_err(|e| MsgHandleErrInternal::from_chan_no_close(e, msg.channel_id))?;
91009105
} else {
91019106
return Err(MsgHandleErrInternal::send_err_msg_no_close("Channel is not funded, cannot splice".to_owned(), msg.channel_id));
91029107
}

0 commit comments

Comments
 (0)