Skip to content

Commit a3f0dd8

Browse files
committed
Add common context getters & move accept checks into fn
1 parent a77c22f commit a3f0dd8

File tree

1 file changed

+187
-127
lines changed

1 file changed

+187
-127
lines changed

lightning/src/ln/channel.rs

Lines changed: 187 additions & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -1002,6 +1002,143 @@ impl<Signer: ChannelSigner> ChannelContext<Signer> {
10021002
self.channel_transaction_parameters.funding_outpoint
10031003
}
10041004

1005+
fn do_accept_channel_checks(&mut self, default_limits: &ChannelHandshakeLimits,
1006+
their_features: &InitFeatures, msg_dust_limit_satoshis: u64, msg_channel_reserve_satoshis: u64,
1007+
msg_to_self_delay: u16, msg_max_accepted_htlcs: u16, msg_htlc_minimum_msat: u64,
1008+
msg_max_htlc_value_in_flight_msat: u64, msg_minimum_depth: u32, msg_channel_type: &Option<ChannelTypeFeatures>,
1009+
msg_shutdown_scriptpubkey: &Option<Script>, msg_funding_pubkey: PublicKey, msg_revocation_basepoint: PublicKey,
1010+
msg_payment_point: PublicKey, msg_delayed_payment_basepoint: PublicKey, msg_htlc_basepoint: PublicKey,
1011+
msg_first_per_commitment_point: PublicKey,
1012+
) -> Result<(), ChannelError> {
1013+
let peer_limits = if let Some(ref limits) = self.inbound_handshake_limits_override { limits } else { default_limits };
1014+
1015+
// Check sanity of message fields:
1016+
if !self.is_outbound() {
1017+
return Err(ChannelError::Close("Got an accept_channel message from an inbound peer".to_owned()));
1018+
}
1019+
if self.channel_state != ChannelState::OurInitSent as u32 {
1020+
return Err(ChannelError::Close("Got an accept_channel message at a strange time".to_owned()));
1021+
}
1022+
if msg_dust_limit_satoshis > 21000000 * 100000000 {
1023+
return Err(ChannelError::Close(format!("Peer never wants payout outputs? dust_limit_satoshis was {}", msg_dust_limit_satoshis)));
1024+
}
1025+
if msg_channel_reserve_satoshis > self.channel_value_satoshis {
1026+
return Err(ChannelError::Close(format!("Bogus channel_reserve_satoshis ({}). Must not be greater than ({})", msg_channel_reserve_satoshis, self.channel_value_satoshis)));
1027+
}
1028+
if msg_dust_limit_satoshis > self.holder_selected_channel_reserve_satoshis {
1029+
return Err(ChannelError::Close(format!("Dust limit ({}) is bigger than our channel reserve ({})", msg_dust_limit_satoshis, self.holder_selected_channel_reserve_satoshis)));
1030+
}
1031+
if msg_channel_reserve_satoshis > self.channel_value_satoshis - self.holder_selected_channel_reserve_satoshis {
1032+
return Err(ChannelError::Close(format!("Bogus channel_reserve_satoshis ({}). Must not be greater than channel value minus our reserve ({})",
1033+
msg_channel_reserve_satoshis, self.channel_value_satoshis - self.holder_selected_channel_reserve_satoshis)));
1034+
}
1035+
let full_channel_value_msat = (self.channel_value_satoshis - msg_channel_reserve_satoshis) * 1000;
1036+
if msg_htlc_minimum_msat >= full_channel_value_msat {
1037+
return Err(ChannelError::Close(format!("Minimum htlc value ({}) is full channel value ({})", msg_htlc_minimum_msat, full_channel_value_msat)));
1038+
}
1039+
let max_delay_acceptable = u16::min(peer_limits.their_to_self_delay, MAX_LOCAL_BREAKDOWN_TIMEOUT);
1040+
if msg_to_self_delay > max_delay_acceptable {
1041+
return Err(ChannelError::Close(format!("They wanted our payments to be delayed by a needlessly long period. Upper limit: {}. Actual: {}", max_delay_acceptable, msg_to_self_delay)));
1042+
}
1043+
if msg_max_accepted_htlcs < 1 {
1044+
return Err(ChannelError::Close("0 max_accepted_htlcs makes for a useless channel".to_owned()));
1045+
}
1046+
if msg_max_accepted_htlcs > MAX_HTLCS {
1047+
return Err(ChannelError::Close(format!("max_accepted_htlcs was {}. It must not be larger than {}", msg_max_accepted_htlcs, MAX_HTLCS)));
1048+
}
1049+
1050+
// Now check against optional parameters as set by config...
1051+
if msg_htlc_minimum_msat > peer_limits.max_htlc_minimum_msat {
1052+
return Err(ChannelError::Close(format!("htlc_minimum_msat ({}) is higher than the user specified limit ({})", msg_htlc_minimum_msat, peer_limits.max_htlc_minimum_msat)));
1053+
}
1054+
if msg_max_htlc_value_in_flight_msat < peer_limits.min_max_htlc_value_in_flight_msat {
1055+
return Err(ChannelError::Close(format!("max_htlc_value_in_flight_msat ({}) is less than the user specified limit ({})", msg_max_htlc_value_in_flight_msat, peer_limits.min_max_htlc_value_in_flight_msat)));
1056+
}
1057+
if msg_channel_reserve_satoshis > peer_limits.max_channel_reserve_satoshis {
1058+
return Err(ChannelError::Close(format!("channel_reserve_satoshis ({}) is higher than the user specified limit ({})", msg_channel_reserve_satoshis, peer_limits.max_channel_reserve_satoshis)));
1059+
}
1060+
if msg_max_accepted_htlcs < peer_limits.min_max_accepted_htlcs {
1061+
return Err(ChannelError::Close(format!("max_accepted_htlcs ({}) is less than the user specified limit ({})", msg_max_accepted_htlcs, peer_limits.min_max_accepted_htlcs)));
1062+
}
1063+
if msg_dust_limit_satoshis < MIN_CHAN_DUST_LIMIT_SATOSHIS {
1064+
return Err(ChannelError::Close(format!("dust_limit_satoshis ({}) is less than the implementation limit ({})", msg_dust_limit_satoshis, MIN_CHAN_DUST_LIMIT_SATOSHIS)));
1065+
}
1066+
if msg_dust_limit_satoshis > MAX_CHAN_DUST_LIMIT_SATOSHIS {
1067+
return Err(ChannelError::Close(format!("dust_limit_satoshis ({}) is greater than the implementation limit ({})", msg_dust_limit_satoshis, MAX_CHAN_DUST_LIMIT_SATOSHIS)));
1068+
}
1069+
if msg_minimum_depth > peer_limits.max_minimum_depth {
1070+
return Err(ChannelError::Close(format!("We consider the minimum depth to be unreasonably large. Expected minimum: ({}). Actual: ({})", peer_limits.max_minimum_depth, msg_minimum_depth)));
1071+
}
1072+
1073+
if let Some(ty) = &msg_channel_type {
1074+
if *ty != self.channel_type {
1075+
return Err(ChannelError::Close("Channel Type in accept_channel didn't match the one sent in open_channel.".to_owned()));
1076+
}
1077+
} else if their_features.supports_channel_type() {
1078+
// Assume they've accepted the channel type as they said they understand it.
1079+
} else {
1080+
let channel_type = ChannelTypeFeatures::from_init(&their_features);
1081+
if channel_type != ChannelTypeFeatures::only_static_remote_key() {
1082+
return Err(ChannelError::Close("Only static_remote_key is supported for non-negotiated channel types".to_owned()));
1083+
}
1084+
self.channel_type = channel_type.clone();
1085+
self.channel_transaction_parameters.channel_type_features = channel_type;
1086+
}
1087+
1088+
let counterparty_shutdown_scriptpubkey = if their_features.supports_upfront_shutdown_script() {
1089+
match &msg_shutdown_scriptpubkey {
1090+
&Some(ref script) => {
1091+
// Peer is signaling upfront_shutdown and has opt-out with a 0-length script. We don't enforce anything
1092+
if script.len() == 0 {
1093+
None
1094+
} else {
1095+
if !script::is_bolt2_compliant(&script, their_features) {
1096+
return Err(ChannelError::Close(format!("Peer is signaling upfront_shutdown but has provided an unacceptable scriptpubkey format: {}", script)));
1097+
}
1098+
Some(script.clone())
1099+
}
1100+
},
1101+
// Peer is signaling upfront shutdown but don't opt-out with correct mechanism (a.k.a 0-length script). Peer looks buggy, we fail the channel
1102+
&None => {
1103+
return Err(ChannelError::Close("Peer is signaling upfront_shutdown but we don't get any script. Use 0-length script to opt-out".to_owned()));
1104+
}
1105+
}
1106+
} else { None };
1107+
1108+
self.counterparty_dust_limit_satoshis = msg_dust_limit_satoshis;
1109+
self.counterparty_max_htlc_value_in_flight_msat = cmp::min(msg_max_htlc_value_in_flight_msat, self.channel_value_satoshis * 1000);
1110+
self.counterparty_selected_channel_reserve_satoshis = Some(msg_channel_reserve_satoshis);
1111+
self.counterparty_htlc_minimum_msat = msg_htlc_minimum_msat;
1112+
self.counterparty_max_accepted_htlcs = msg_max_accepted_htlcs;
1113+
1114+
if peer_limits.trust_own_funding_0conf {
1115+
self.minimum_depth = Some(msg_minimum_depth);
1116+
} else {
1117+
self.minimum_depth = Some(cmp::max(1, msg_minimum_depth));
1118+
}
1119+
1120+
let counterparty_pubkeys = ChannelPublicKeys {
1121+
funding_pubkey: msg_funding_pubkey,
1122+
revocation_basepoint: msg_revocation_basepoint,
1123+
payment_point: msg_payment_point,
1124+
delayed_payment_basepoint: msg_delayed_payment_basepoint,
1125+
htlc_basepoint: msg_htlc_basepoint
1126+
};
1127+
1128+
self.channel_transaction_parameters.counterparty_parameters = Some(CounterpartyChannelTransactionParameters {
1129+
selected_contest_delay: msg_to_self_delay,
1130+
pubkeys: counterparty_pubkeys,
1131+
});
1132+
1133+
self.counterparty_cur_commitment_point = Some(msg_first_per_commitment_point);
1134+
self.counterparty_shutdown_scriptpubkey = counterparty_shutdown_scriptpubkey;
1135+
1136+
self.channel_state = ChannelState::OurInitSent as u32 | ChannelState::TheirInitSent as u32;
1137+
self.inbound_handshake_limits_override = None; // We're done enforcing limits on our peer's handshake now.
1138+
1139+
Ok(())
1140+
}
1141+
10051142
/// Returns the block hash in which our funding transaction was confirmed.
10061143
pub fn get_funding_tx_confirmed_in(&self) -> Option<BlockHash> {
10071144
self.funding_tx_confirmed_in
@@ -2094,6 +2231,14 @@ struct CommitmentTxInfoCached {
20942231
}
20952232

20962233
impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
2234+
pub fn context(&self) -> &ChannelContext<Signer> {
2235+
&self.context
2236+
}
2237+
2238+
pub fn context_mut(&mut self) -> &mut ChannelContext<Signer> {
2239+
&mut self.context
2240+
}
2241+
20972242
fn check_remote_fee<F: Deref, L: Deref>(fee_estimator: &LowerBoundedFeeEstimator<F>,
20982243
feerate_per_kw: u32, cur_feerate_per_kw: Option<u32>, logger: &L)
20992244
-> Result<(), ChannelError> where F::Target: FeeEstimator, L::Target: Logger,
@@ -5711,6 +5856,14 @@ impl<Signer: WriteableEcdsaChannelSigner> OutboundV1Channel<Signer> {
57115856
})
57125857
}
57135858

5859+
pub fn context(&self) -> &ChannelContext<Signer> {
5860+
&self.context
5861+
}
5862+
5863+
pub fn context_mut(&mut self) -> &mut ChannelContext<Signer> {
5864+
&mut self.context
5865+
}
5866+
57145867
/// If an Err is returned, it is a ChannelError::Close (for get_outbound_funding_created)
57155868
fn get_outbound_funding_created_signature<L: Deref>(&mut self, logger: &L) -> Result<Signature, ChannelError> where L::Target: Logger {
57165869
let counterparty_keys = self.context.build_remote_transaction_keys();
@@ -5850,133 +6003,12 @@ impl<Signer: WriteableEcdsaChannelSigner> OutboundV1Channel<Signer> {
58506003

58516004
// Message handlers
58526005
pub fn accept_channel(&mut self, msg: &msgs::AcceptChannel, default_limits: &ChannelHandshakeLimits, their_features: &InitFeatures) -> Result<(), ChannelError> {
5853-
let peer_limits = if let Some(ref limits) = self.context.inbound_handshake_limits_override { limits } else { default_limits };
5854-
5855-
// Check sanity of message fields:
5856-
if !self.context.is_outbound() {
5857-
return Err(ChannelError::Close("Got an accept_channel message from an inbound peer".to_owned()));
5858-
}
5859-
if self.context.channel_state != ChannelState::OurInitSent as u32 {
5860-
return Err(ChannelError::Close("Got an accept_channel message at a strange time".to_owned()));
5861-
}
5862-
if msg.dust_limit_satoshis > 21000000 * 100000000 {
5863-
return Err(ChannelError::Close(format!("Peer never wants payout outputs? dust_limit_satoshis was {}", msg.dust_limit_satoshis)));
5864-
}
5865-
if msg.channel_reserve_satoshis > self.context.channel_value_satoshis {
5866-
return Err(ChannelError::Close(format!("Bogus channel_reserve_satoshis ({}). Must not be greater than ({})", msg.channel_reserve_satoshis, self.context.channel_value_satoshis)));
5867-
}
5868-
if msg.dust_limit_satoshis > self.context.holder_selected_channel_reserve_satoshis {
5869-
return Err(ChannelError::Close(format!("Dust limit ({}) is bigger than our channel reserve ({})", msg.dust_limit_satoshis, self.context.holder_selected_channel_reserve_satoshis)));
5870-
}
5871-
if msg.channel_reserve_satoshis > self.context.channel_value_satoshis - self.context.holder_selected_channel_reserve_satoshis {
5872-
return Err(ChannelError::Close(format!("Bogus channel_reserve_satoshis ({}). Must not be greater than channel value minus our reserve ({})",
5873-
msg.channel_reserve_satoshis, self.context.channel_value_satoshis - self.context.holder_selected_channel_reserve_satoshis)));
5874-
}
5875-
let full_channel_value_msat = (self.context.channel_value_satoshis - msg.channel_reserve_satoshis) * 1000;
5876-
if msg.htlc_minimum_msat >= full_channel_value_msat {
5877-
return Err(ChannelError::Close(format!("Minimum htlc value ({}) is full channel value ({})", msg.htlc_minimum_msat, full_channel_value_msat)));
5878-
}
5879-
let max_delay_acceptable = u16::min(peer_limits.their_to_self_delay, MAX_LOCAL_BREAKDOWN_TIMEOUT);
5880-
if msg.to_self_delay > max_delay_acceptable {
5881-
return Err(ChannelError::Close(format!("They wanted our payments to be delayed by a needlessly long period. Upper limit: {}. Actual: {}", max_delay_acceptable, msg.to_self_delay)));
5882-
}
5883-
if msg.max_accepted_htlcs < 1 {
5884-
return Err(ChannelError::Close("0 max_accepted_htlcs makes for a useless channel".to_owned()));
5885-
}
5886-
if msg.max_accepted_htlcs > MAX_HTLCS {
5887-
return Err(ChannelError::Close(format!("max_accepted_htlcs was {}. It must not be larger than {}", msg.max_accepted_htlcs, MAX_HTLCS)));
5888-
}
5889-
5890-
// Now check against optional parameters as set by config...
5891-
if msg.htlc_minimum_msat > peer_limits.max_htlc_minimum_msat {
5892-
return Err(ChannelError::Close(format!("htlc_minimum_msat ({}) is higher than the user specified limit ({})", msg.htlc_minimum_msat, peer_limits.max_htlc_minimum_msat)));
5893-
}
5894-
if msg.max_htlc_value_in_flight_msat < peer_limits.min_max_htlc_value_in_flight_msat {
5895-
return Err(ChannelError::Close(format!("max_htlc_value_in_flight_msat ({}) is less than the user specified limit ({})", msg.max_htlc_value_in_flight_msat, peer_limits.min_max_htlc_value_in_flight_msat)));
5896-
}
5897-
if msg.channel_reserve_satoshis > peer_limits.max_channel_reserve_satoshis {
5898-
return Err(ChannelError::Close(format!("channel_reserve_satoshis ({}) is higher than the user specified limit ({})", msg.channel_reserve_satoshis, peer_limits.max_channel_reserve_satoshis)));
5899-
}
5900-
if msg.max_accepted_htlcs < peer_limits.min_max_accepted_htlcs {
5901-
return Err(ChannelError::Close(format!("max_accepted_htlcs ({}) is less than the user specified limit ({})", msg.max_accepted_htlcs, peer_limits.min_max_accepted_htlcs)));
5902-
}
5903-
if msg.dust_limit_satoshis < MIN_CHAN_DUST_LIMIT_SATOSHIS {
5904-
return Err(ChannelError::Close(format!("dust_limit_satoshis ({}) is less than the implementation limit ({})", msg.dust_limit_satoshis, MIN_CHAN_DUST_LIMIT_SATOSHIS)));
5905-
}
5906-
if msg.dust_limit_satoshis > MAX_CHAN_DUST_LIMIT_SATOSHIS {
5907-
return Err(ChannelError::Close(format!("dust_limit_satoshis ({}) is greater than the implementation limit ({})", msg.dust_limit_satoshis, MAX_CHAN_DUST_LIMIT_SATOSHIS)));
5908-
}
5909-
if msg.minimum_depth > peer_limits.max_minimum_depth {
5910-
return Err(ChannelError::Close(format!("We consider the minimum depth to be unreasonably large. Expected minimum: ({}). Actual: ({})", peer_limits.max_minimum_depth, msg.minimum_depth)));
5911-
}
5912-
5913-
if let Some(ty) = &msg.channel_type {
5914-
if *ty != self.context.channel_type {
5915-
return Err(ChannelError::Close("Channel Type in accept_channel didn't match the one sent in open_channel.".to_owned()));
5916-
}
5917-
} else if their_features.supports_channel_type() {
5918-
// Assume they've accepted the channel type as they said they understand it.
5919-
} else {
5920-
let channel_type = ChannelTypeFeatures::from_init(&their_features);
5921-
if channel_type != ChannelTypeFeatures::only_static_remote_key() {
5922-
return Err(ChannelError::Close("Only static_remote_key is supported for non-negotiated channel types".to_owned()));
5923-
}
5924-
self.context.channel_type = channel_type.clone();
5925-
self.context.channel_transaction_parameters.channel_type_features = channel_type;
5926-
}
5927-
5928-
let counterparty_shutdown_scriptpubkey = if their_features.supports_upfront_shutdown_script() {
5929-
match &msg.shutdown_scriptpubkey {
5930-
&Some(ref script) => {
5931-
// Peer is signaling upfront_shutdown and has opt-out with a 0-length script. We don't enforce anything
5932-
if script.len() == 0 {
5933-
None
5934-
} else {
5935-
if !script::is_bolt2_compliant(&script, their_features) {
5936-
return Err(ChannelError::Close(format!("Peer is signaling upfront_shutdown but has provided an unacceptable scriptpubkey format: {}", script)));
5937-
}
5938-
Some(script.clone())
5939-
}
5940-
},
5941-
// Peer is signaling upfront shutdown but don't opt-out with correct mechanism (a.k.a 0-length script). Peer looks buggy, we fail the channel
5942-
&None => {
5943-
return Err(ChannelError::Close("Peer is signaling upfront_shutdown but we don't get any script. Use 0-length script to opt-out".to_owned()));
5944-
}
5945-
}
5946-
} else { None };
5947-
5948-
self.context.counterparty_dust_limit_satoshis = msg.dust_limit_satoshis;
5949-
self.context.counterparty_max_htlc_value_in_flight_msat = cmp::min(msg.max_htlc_value_in_flight_msat, self.context.channel_value_satoshis * 1000);
5950-
self.context.counterparty_selected_channel_reserve_satoshis = Some(msg.channel_reserve_satoshis);
5951-
self.context.counterparty_htlc_minimum_msat = msg.htlc_minimum_msat;
5952-
self.context.counterparty_max_accepted_htlcs = msg.max_accepted_htlcs;
5953-
5954-
if peer_limits.trust_own_funding_0conf {
5955-
self.context.minimum_depth = Some(msg.minimum_depth);
5956-
} else {
5957-
self.context.minimum_depth = Some(cmp::max(1, msg.minimum_depth));
5958-
}
5959-
5960-
let counterparty_pubkeys = ChannelPublicKeys {
5961-
funding_pubkey: msg.funding_pubkey,
5962-
revocation_basepoint: msg.revocation_basepoint,
5963-
payment_point: msg.payment_point,
5964-
delayed_payment_basepoint: msg.delayed_payment_basepoint,
5965-
htlc_basepoint: msg.htlc_basepoint
5966-
};
5967-
5968-
self.context.channel_transaction_parameters.counterparty_parameters = Some(CounterpartyChannelTransactionParameters {
5969-
selected_contest_delay: msg.to_self_delay,
5970-
pubkeys: counterparty_pubkeys,
5971-
});
5972-
5973-
self.context.counterparty_cur_commitment_point = Some(msg.first_per_commitment_point);
5974-
self.context.counterparty_shutdown_scriptpubkey = counterparty_shutdown_scriptpubkey;
5975-
5976-
self.context.channel_state = ChannelState::OurInitSent as u32 | ChannelState::TheirInitSent as u32;
5977-
self.context.inbound_handshake_limits_override = None; // We're done enforcing limits on our peer's handshake now.
5978-
5979-
Ok(())
6006+
self.context.do_accept_channel_checks(
6007+
default_limits, their_features, msg.dust_limit_satoshis, msg.channel_reserve_satoshis,
6008+
msg.to_self_delay, msg.max_accepted_htlcs, msg.htlc_minimum_msat,
6009+
msg.max_htlc_value_in_flight_msat, msg.minimum_depth, &msg.channel_type,
6010+
&msg.shutdown_scriptpubkey, msg.funding_pubkey, msg.revocation_basepoint, msg.payment_point,
6011+
msg.delayed_payment_basepoint, msg.htlc_basepoint, msg.first_per_commitment_point)
59806012
}
59816013
}
59826014

@@ -6316,6 +6348,14 @@ impl<Signer: WriteableEcdsaChannelSigner> InboundV1Channel<Signer> {
63166348
Ok(chan)
63176349
}
63186350

6351+
pub fn context(&self) -> &ChannelContext<Signer> {
6352+
&self.context
6353+
}
6354+
6355+
pub fn context_mut(&mut self) -> &mut ChannelContext<Signer> {
6356+
&mut self.context
6357+
}
6358+
63196359
pub fn is_awaiting_accept(&self) -> bool {
63206360
self.context.inbound_awaiting_accept
63216361
}
@@ -6742,6 +6782,14 @@ impl<Signer: WriteableEcdsaChannelSigner> OutboundV2Channel<Signer> {
67426782
})
67436783
}
67446784

6785+
pub fn context(&self) -> &ChannelContext<Signer> {
6786+
&self.context.common
6787+
}
6788+
6789+
pub fn context_mut(&mut self) -> &mut ChannelContext<Signer> {
6790+
&mut self.context.common
6791+
}
6792+
67456793
pub fn get_open_channel_v2(&self, chain_hash: BlockHash) -> msgs::OpenChannelV2 {
67466794
if self.context.common.channel_state != ChannelState::OurInitSent as u32 {
67476795
panic!("Cannot generate an open_channel2 after we've moved forward");
@@ -7153,6 +7201,18 @@ impl<Signer: WriteableEcdsaChannelSigner> InboundV2Channel<Signer> {
71537201
Ok(chan)
71547202
}
71557203

7204+
pub fn context(&self) -> &ChannelContext<Signer> {
7205+
&self.context.common
7206+
}
7207+
7208+
pub fn context_mut(&mut self) -> &mut ChannelContext<Signer> {
7209+
&mut self.context.common
7210+
}
7211+
7212+
pub fn is_awaiting_accept(&self) -> bool {
7213+
self.context.common.inbound_awaiting_accept
7214+
}
7215+
71567216
/// Marks an inbound channel as accepted and generates a [`msgs::AcceptChannelV2`] message which
71577217
/// should be sent back to the counterparty node.
71587218
///

0 commit comments

Comments
 (0)