Skip to content

Commit 7857d24

Browse files
committed
Move accept_channel checks into ChannelContext::do_accept_channel_checks
This is done ahead of getting the dual-funding implementation to reduce refactoring noise there.
1 parent cc9fc65 commit 7857d24

File tree

1 file changed

+140
-130
lines changed

1 file changed

+140
-130
lines changed

lightning/src/ln/channel.rs

+140-130
Original file line numberDiff line numberDiff line change
@@ -2146,6 +2146,141 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
21462146
}
21472147
}
21482148

2149+
pub fn do_accept_channel_checks(
2150+
&mut self, default_limits: &ChannelHandshakeLimits, their_features: &InitFeatures,
2151+
common_fields: &msgs::CommonAcceptChannelFields, channel_reserve_satoshis: u64,
2152+
) -> Result<(), ChannelError> {
2153+
let peer_limits = if let Some(ref limits) = self.inbound_handshake_limits_override { limits } else { default_limits };
2154+
2155+
// Check sanity of message fields:
2156+
if !self.is_outbound() {
2157+
return Err(ChannelError::close("Got an accept_channel message from an inbound peer".to_owned()));
2158+
}
2159+
if !matches!(self.channel_state, ChannelState::NegotiatingFunding(flags) if flags == NegotiatingFundingFlags::OUR_INIT_SENT) {
2160+
return Err(ChannelError::close("Got an accept_channel message at a strange time".to_owned()));
2161+
}
2162+
if common_fields.dust_limit_satoshis > 21000000 * 100000000 {
2163+
return Err(ChannelError::close(format!("Peer never wants payout outputs? dust_limit_satoshis was {}", common_fields.dust_limit_satoshis)));
2164+
}
2165+
if channel_reserve_satoshis > self.channel_value_satoshis {
2166+
return Err(ChannelError::close(format!("Bogus channel_reserve_satoshis ({}). Must not be greater than ({})", channel_reserve_satoshis, self.channel_value_satoshis)));
2167+
}
2168+
if common_fields.dust_limit_satoshis > self.holder_selected_channel_reserve_satoshis {
2169+
return Err(ChannelError::close(format!("Dust limit ({}) is bigger than our channel reserve ({})", common_fields.dust_limit_satoshis, self.holder_selected_channel_reserve_satoshis)));
2170+
}
2171+
if channel_reserve_satoshis > self.channel_value_satoshis - self.holder_selected_channel_reserve_satoshis {
2172+
return Err(ChannelError::close(format!("Bogus channel_reserve_satoshis ({}). Must not be greater than channel value minus our reserve ({})",
2173+
channel_reserve_satoshis, self.channel_value_satoshis - self.holder_selected_channel_reserve_satoshis)));
2174+
}
2175+
let full_channel_value_msat = (self.channel_value_satoshis - channel_reserve_satoshis) * 1000;
2176+
if common_fields.htlc_minimum_msat >= full_channel_value_msat {
2177+
return Err(ChannelError::close(format!("Minimum htlc value ({}) is full channel value ({})", common_fields.htlc_minimum_msat, full_channel_value_msat)));
2178+
}
2179+
let max_delay_acceptable = u16::min(peer_limits.their_to_self_delay, MAX_LOCAL_BREAKDOWN_TIMEOUT);
2180+
if common_fields.to_self_delay > max_delay_acceptable {
2181+
return Err(ChannelError::close(format!("They wanted our payments to be delayed by a needlessly long period. Upper limit: {}. Actual: {}", max_delay_acceptable, common_fields.to_self_delay)));
2182+
}
2183+
if common_fields.max_accepted_htlcs < 1 {
2184+
return Err(ChannelError::close("0 max_accepted_htlcs makes for a useless channel".to_owned()));
2185+
}
2186+
if common_fields.max_accepted_htlcs > MAX_HTLCS {
2187+
return Err(ChannelError::close(format!("max_accepted_htlcs was {}. It must not be larger than {}", common_fields.max_accepted_htlcs, MAX_HTLCS)));
2188+
}
2189+
2190+
// Now check against optional parameters as set by config...
2191+
if common_fields.htlc_minimum_msat > peer_limits.max_htlc_minimum_msat {
2192+
return Err(ChannelError::close(format!("htlc_minimum_msat ({}) is higher than the user specified limit ({})", common_fields.htlc_minimum_msat, peer_limits.max_htlc_minimum_msat)));
2193+
}
2194+
if common_fields.max_htlc_value_in_flight_msat < peer_limits.min_max_htlc_value_in_flight_msat {
2195+
return Err(ChannelError::close(format!("max_htlc_value_in_flight_msat ({}) is less than the user specified limit ({})", common_fields.max_htlc_value_in_flight_msat, peer_limits.min_max_htlc_value_in_flight_msat)));
2196+
}
2197+
if channel_reserve_satoshis > peer_limits.max_channel_reserve_satoshis {
2198+
return Err(ChannelError::close(format!("channel_reserve_satoshis ({}) is higher than the user specified limit ({})", channel_reserve_satoshis, peer_limits.max_channel_reserve_satoshis)));
2199+
}
2200+
if common_fields.max_accepted_htlcs < peer_limits.min_max_accepted_htlcs {
2201+
return Err(ChannelError::close(format!("max_accepted_htlcs ({}) is less than the user specified limit ({})", common_fields.max_accepted_htlcs, peer_limits.min_max_accepted_htlcs)));
2202+
}
2203+
if common_fields.dust_limit_satoshis < MIN_CHAN_DUST_LIMIT_SATOSHIS {
2204+
return Err(ChannelError::close(format!("dust_limit_satoshis ({}) is less than the implementation limit ({})", common_fields.dust_limit_satoshis, MIN_CHAN_DUST_LIMIT_SATOSHIS)));
2205+
}
2206+
if common_fields.dust_limit_satoshis > MAX_CHAN_DUST_LIMIT_SATOSHIS {
2207+
return Err(ChannelError::close(format!("dust_limit_satoshis ({}) is greater than the implementation limit ({})", common_fields.dust_limit_satoshis, MAX_CHAN_DUST_LIMIT_SATOSHIS)));
2208+
}
2209+
if common_fields.minimum_depth > peer_limits.max_minimum_depth {
2210+
return Err(ChannelError::close(format!("We consider the minimum depth to be unreasonably large. Expected minimum: ({}). Actual: ({})", peer_limits.max_minimum_depth, common_fields.minimum_depth)));
2211+
}
2212+
2213+
if let Some(ty) = &common_fields.channel_type {
2214+
if *ty != self.channel_type {
2215+
return Err(ChannelError::close("Channel Type in accept_channel didn't match the one sent in open_channel.".to_owned()));
2216+
}
2217+
} else if their_features.supports_channel_type() {
2218+
// Assume they've accepted the channel type as they said they understand it.
2219+
} else {
2220+
let channel_type = ChannelTypeFeatures::from_init(&their_features);
2221+
if channel_type != ChannelTypeFeatures::only_static_remote_key() {
2222+
return Err(ChannelError::close("Only static_remote_key is supported for non-negotiated channel types".to_owned()));
2223+
}
2224+
self.channel_type = channel_type.clone();
2225+
self.channel_transaction_parameters.channel_type_features = channel_type;
2226+
}
2227+
2228+
let counterparty_shutdown_scriptpubkey = if their_features.supports_upfront_shutdown_script() {
2229+
match &common_fields.shutdown_scriptpubkey {
2230+
&Some(ref script) => {
2231+
// Peer is signaling upfront_shutdown and has opt-out with a 0-length script. We don't enforce anything
2232+
if script.len() == 0 {
2233+
None
2234+
} else {
2235+
if !script::is_bolt2_compliant(&script, their_features) {
2236+
return Err(ChannelError::close(format!("Peer is signaling upfront_shutdown but has provided an unacceptable scriptpubkey format: {}", script)));
2237+
}
2238+
Some(script.clone())
2239+
}
2240+
},
2241+
// 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
2242+
&None => {
2243+
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()));
2244+
}
2245+
}
2246+
} else { None };
2247+
2248+
self.counterparty_dust_limit_satoshis = common_fields.dust_limit_satoshis;
2249+
self.counterparty_max_htlc_value_in_flight_msat = cmp::min(common_fields.max_htlc_value_in_flight_msat, self.channel_value_satoshis * 1000);
2250+
self.counterparty_selected_channel_reserve_satoshis = Some(channel_reserve_satoshis);
2251+
self.counterparty_htlc_minimum_msat = common_fields.htlc_minimum_msat;
2252+
self.counterparty_max_accepted_htlcs = common_fields.max_accepted_htlcs;
2253+
2254+
if peer_limits.trust_own_funding_0conf {
2255+
self.minimum_depth = Some(common_fields.minimum_depth);
2256+
} else {
2257+
self.minimum_depth = Some(cmp::max(1, common_fields.minimum_depth));
2258+
}
2259+
2260+
let counterparty_pubkeys = ChannelPublicKeys {
2261+
funding_pubkey: common_fields.funding_pubkey,
2262+
revocation_basepoint: RevocationBasepoint::from(common_fields.revocation_basepoint),
2263+
payment_point: common_fields.payment_basepoint,
2264+
delayed_payment_basepoint: DelayedPaymentBasepoint::from(common_fields.delayed_payment_basepoint),
2265+
htlc_basepoint: HtlcBasepoint::from(common_fields.htlc_basepoint)
2266+
};
2267+
2268+
self.channel_transaction_parameters.counterparty_parameters = Some(CounterpartyChannelTransactionParameters {
2269+
selected_contest_delay: common_fields.to_self_delay,
2270+
pubkeys: counterparty_pubkeys,
2271+
});
2272+
2273+
self.counterparty_cur_commitment_point = Some(common_fields.first_per_commitment_point);
2274+
self.counterparty_shutdown_scriptpubkey = counterparty_shutdown_scriptpubkey;
2275+
2276+
self.channel_state = ChannelState::NegotiatingFunding(
2277+
NegotiatingFundingFlags::OUR_INIT_SENT | NegotiatingFundingFlags::THEIR_INIT_SENT
2278+
);
2279+
self.inbound_handshake_limits_override = None; // We're done enforcing limits on our peer's handshake now.
2280+
2281+
Ok(())
2282+
}
2283+
21492284
/// Returns the block hash in which our funding transaction was confirmed.
21502285
pub fn get_funding_tx_confirmed_in(&self) -> Option<BlockHash> {
21512286
self.funding_tx_confirmed_in
@@ -7497,136 +7632,11 @@ impl<SP: Deref> OutboundV1Channel<SP> where SP::Target: SignerProvider {
74977632
}
74987633

74997634
// Message handlers
7500-
pub fn accept_channel(&mut self, msg: &msgs::AcceptChannel, default_limits: &ChannelHandshakeLimits, their_features: &InitFeatures) -> Result<(), ChannelError> {
7501-
let peer_limits = if let Some(ref limits) = self.context.inbound_handshake_limits_override { limits } else { default_limits };
7502-
7503-
// Check sanity of message fields:
7504-
if !self.context.is_outbound() {
7505-
return Err(ChannelError::close("Got an accept_channel message from an inbound peer".to_owned()));
7506-
}
7507-
if !matches!(self.context.channel_state, ChannelState::NegotiatingFunding(flags) if flags == NegotiatingFundingFlags::OUR_INIT_SENT) {
7508-
return Err(ChannelError::close("Got an accept_channel message at a strange time".to_owned()));
7509-
}
7510-
if msg.common_fields.dust_limit_satoshis > 21000000 * 100000000 {
7511-
return Err(ChannelError::close(format!("Peer never wants payout outputs? dust_limit_satoshis was {}", msg.common_fields.dust_limit_satoshis)));
7512-
}
7513-
if msg.channel_reserve_satoshis > self.context.channel_value_satoshis {
7514-
return Err(ChannelError::close(format!("Bogus channel_reserve_satoshis ({}). Must not be greater than ({})", msg.channel_reserve_satoshis, self.context.channel_value_satoshis)));
7515-
}
7516-
if msg.common_fields.dust_limit_satoshis > self.context.holder_selected_channel_reserve_satoshis {
7517-
return Err(ChannelError::close(format!("Dust limit ({}) is bigger than our channel reserve ({})", msg.common_fields.dust_limit_satoshis, self.context.holder_selected_channel_reserve_satoshis)));
7518-
}
7519-
if msg.channel_reserve_satoshis > self.context.channel_value_satoshis - self.context.holder_selected_channel_reserve_satoshis {
7520-
return Err(ChannelError::close(format!("Bogus channel_reserve_satoshis ({}). Must not be greater than channel value minus our reserve ({})",
7521-
msg.channel_reserve_satoshis, self.context.channel_value_satoshis - self.context.holder_selected_channel_reserve_satoshis)));
7522-
}
7523-
let full_channel_value_msat = (self.context.channel_value_satoshis - msg.channel_reserve_satoshis) * 1000;
7524-
if msg.common_fields.htlc_minimum_msat >= full_channel_value_msat {
7525-
return Err(ChannelError::close(format!("Minimum htlc value ({}) is full channel value ({})", msg.common_fields.htlc_minimum_msat, full_channel_value_msat)));
7526-
}
7527-
let max_delay_acceptable = u16::min(peer_limits.their_to_self_delay, MAX_LOCAL_BREAKDOWN_TIMEOUT);
7528-
if msg.common_fields.to_self_delay > max_delay_acceptable {
7529-
return Err(ChannelError::close(format!("They wanted our payments to be delayed by a needlessly long period. Upper limit: {}. Actual: {}", max_delay_acceptable, msg.common_fields.to_self_delay)));
7530-
}
7531-
if msg.common_fields.max_accepted_htlcs < 1 {
7532-
return Err(ChannelError::close("0 max_accepted_htlcs makes for a useless channel".to_owned()));
7533-
}
7534-
if msg.common_fields.max_accepted_htlcs > MAX_HTLCS {
7535-
return Err(ChannelError::close(format!("max_accepted_htlcs was {}. It must not be larger than {}", msg.common_fields.max_accepted_htlcs, MAX_HTLCS)));
7536-
}
7537-
7538-
// Now check against optional parameters as set by config...
7539-
if msg.common_fields.htlc_minimum_msat > peer_limits.max_htlc_minimum_msat {
7540-
return Err(ChannelError::close(format!("htlc_minimum_msat ({}) is higher than the user specified limit ({})", msg.common_fields.htlc_minimum_msat, peer_limits.max_htlc_minimum_msat)));
7541-
}
7542-
if msg.common_fields.max_htlc_value_in_flight_msat < peer_limits.min_max_htlc_value_in_flight_msat {
7543-
return Err(ChannelError::close(format!("max_htlc_value_in_flight_msat ({}) is less than the user specified limit ({})", msg.common_fields.max_htlc_value_in_flight_msat, peer_limits.min_max_htlc_value_in_flight_msat)));
7544-
}
7545-
if msg.channel_reserve_satoshis > peer_limits.max_channel_reserve_satoshis {
7546-
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)));
7547-
}
7548-
if msg.common_fields.max_accepted_htlcs < peer_limits.min_max_accepted_htlcs {
7549-
return Err(ChannelError::close(format!("max_accepted_htlcs ({}) is less than the user specified limit ({})", msg.common_fields.max_accepted_htlcs, peer_limits.min_max_accepted_htlcs)));
7550-
}
7551-
if msg.common_fields.dust_limit_satoshis < MIN_CHAN_DUST_LIMIT_SATOSHIS {
7552-
return Err(ChannelError::close(format!("dust_limit_satoshis ({}) is less than the implementation limit ({})", msg.common_fields.dust_limit_satoshis, MIN_CHAN_DUST_LIMIT_SATOSHIS)));
7553-
}
7554-
if msg.common_fields.dust_limit_satoshis > MAX_CHAN_DUST_LIMIT_SATOSHIS {
7555-
return Err(ChannelError::close(format!("dust_limit_satoshis ({}) is greater than the implementation limit ({})", msg.common_fields.dust_limit_satoshis, MAX_CHAN_DUST_LIMIT_SATOSHIS)));
7556-
}
7557-
if msg.common_fields.minimum_depth > peer_limits.max_minimum_depth {
7558-
return Err(ChannelError::close(format!("We consider the minimum depth to be unreasonably large. Expected minimum: ({}). Actual: ({})", peer_limits.max_minimum_depth, msg.common_fields.minimum_depth)));
7559-
}
7560-
7561-
if let Some(ty) = &msg.common_fields.channel_type {
7562-
if *ty != self.context.channel_type {
7563-
return Err(ChannelError::close("Channel Type in accept_channel didn't match the one sent in open_channel.".to_owned()));
7564-
}
7565-
} else if their_features.supports_channel_type() {
7566-
// Assume they've accepted the channel type as they said they understand it.
7567-
} else {
7568-
let channel_type = ChannelTypeFeatures::from_init(&their_features);
7569-
if channel_type != ChannelTypeFeatures::only_static_remote_key() {
7570-
return Err(ChannelError::close("Only static_remote_key is supported for non-negotiated channel types".to_owned()));
7571-
}
7572-
self.context.channel_type = channel_type.clone();
7573-
self.context.channel_transaction_parameters.channel_type_features = channel_type;
7574-
}
7575-
7576-
let counterparty_shutdown_scriptpubkey = if their_features.supports_upfront_shutdown_script() {
7577-
match &msg.common_fields.shutdown_scriptpubkey {
7578-
&Some(ref script) => {
7579-
// Peer is signaling upfront_shutdown and has opt-out with a 0-length script. We don't enforce anything
7580-
if script.len() == 0 {
7581-
None
7582-
} else {
7583-
if !script::is_bolt2_compliant(&script, their_features) {
7584-
return Err(ChannelError::close(format!("Peer is signaling upfront_shutdown but has provided an unacceptable scriptpubkey format: {}", script)));
7585-
}
7586-
Some(script.clone())
7587-
}
7588-
},
7589-
// 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
7590-
&None => {
7591-
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()));
7592-
}
7593-
}
7594-
} else { None };
7595-
7596-
self.context.counterparty_dust_limit_satoshis = msg.common_fields.dust_limit_satoshis;
7597-
self.context.counterparty_max_htlc_value_in_flight_msat = cmp::min(msg.common_fields.max_htlc_value_in_flight_msat, self.context.channel_value_satoshis * 1000);
7598-
self.context.counterparty_selected_channel_reserve_satoshis = Some(msg.channel_reserve_satoshis);
7599-
self.context.counterparty_htlc_minimum_msat = msg.common_fields.htlc_minimum_msat;
7600-
self.context.counterparty_max_accepted_htlcs = msg.common_fields.max_accepted_htlcs;
7601-
7602-
if peer_limits.trust_own_funding_0conf {
7603-
self.context.minimum_depth = Some(msg.common_fields.minimum_depth);
7604-
} else {
7605-
self.context.minimum_depth = Some(cmp::max(1, msg.common_fields.minimum_depth));
7606-
}
7607-
7608-
let counterparty_pubkeys = ChannelPublicKeys {
7609-
funding_pubkey: msg.common_fields.funding_pubkey,
7610-
revocation_basepoint: RevocationBasepoint::from(msg.common_fields.revocation_basepoint),
7611-
payment_point: msg.common_fields.payment_basepoint,
7612-
delayed_payment_basepoint: DelayedPaymentBasepoint::from(msg.common_fields.delayed_payment_basepoint),
7613-
htlc_basepoint: HtlcBasepoint::from(msg.common_fields.htlc_basepoint)
7614-
};
7615-
7616-
self.context.channel_transaction_parameters.counterparty_parameters = Some(CounterpartyChannelTransactionParameters {
7617-
selected_contest_delay: msg.common_fields.to_self_delay,
7618-
pubkeys: counterparty_pubkeys,
7619-
});
7620-
7621-
self.context.counterparty_cur_commitment_point = Some(msg.common_fields.first_per_commitment_point);
7622-
self.context.counterparty_shutdown_scriptpubkey = counterparty_shutdown_scriptpubkey;
7623-
7624-
self.context.channel_state = ChannelState::NegotiatingFunding(
7625-
NegotiatingFundingFlags::OUR_INIT_SENT | NegotiatingFundingFlags::THEIR_INIT_SENT
7626-
);
7627-
self.context.inbound_handshake_limits_override = None; // We're done enforcing limits on our peer's handshake now.
7628-
7629-
Ok(())
7635+
pub fn accept_channel(
7636+
&mut self, msg: &msgs::AcceptChannel, default_limits: &ChannelHandshakeLimits,
7637+
their_features: &InitFeatures
7638+
) -> Result<(), ChannelError> {
7639+
self.context.do_accept_channel_checks(default_limits, their_features, &msg.common_fields, msg.channel_reserve_satoshis)
76307640
}
76317641

76327642
/// Handles a funding_signed message from the remote end.

0 commit comments

Comments
 (0)