Skip to content

Commit e3fcbb6

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 e3fcbb6

File tree

1 file changed

+142
-130
lines changed

1 file changed

+142
-130
lines changed

lightning/src/ln/channel.rs

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

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

74997636
// 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(())
7637+
pub fn accept_channel(
7638+
&mut self, msg: &msgs::AcceptChannel, default_limits: &ChannelHandshakeLimits,
7639+
their_features: &InitFeatures
7640+
) -> Result<(), ChannelError> {
7641+
self.context.do_accept_channel_checks(default_limits, their_features, &msg.common_fields, msg.channel_reserve_satoshis)
76307642
}
76317643

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

0 commit comments

Comments
 (0)