Skip to content

Commit 05d73ed

Browse files
committed
f - Check KeysInterface::get_shutdown_scriptpubkey
Check that the user-provided shutdown_scriptpubkey is compatible with the counterparty's features (option_shutdown_anysegwit). TODO: Implement for ChannelManager::close_channel TODO: Add unit tests
1 parent 541193e commit 05d73ed

File tree

2 files changed

+45
-20
lines changed

2 files changed

+45
-20
lines changed

lightning/src/ln/channel.rs

Lines changed: 39 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -567,7 +567,7 @@ impl<Signer: Sign> Channel<Signer> {
567567
}
568568

569569
// Constructors:
570-
pub fn new_outbound<K: Deref, F: Deref>(fee_estimator: &F, keys_provider: &K, counterparty_node_id: PublicKey, channel_value_satoshis: u64, push_msat: u64, user_id: u64, config: &UserConfig) -> Result<Channel<Signer>, APIError>
570+
pub fn new_outbound<K: Deref, F: Deref>(fee_estimator: &F, keys_provider: &K, counterparty_node_id: PublicKey, their_features: InitFeatures, channel_value_satoshis: u64, push_msat: u64, user_id: u64, config: &UserConfig) -> Result<Channel<Signer>, APIError>
571571
where K::Target: KeysInterface<Signer = Signer>,
572572
F::Target: FeeEstimator,
573573
{
@@ -597,9 +597,13 @@ impl<Signer: Sign> Channel<Signer> {
597597

598598
let shutdown_scriptpubkey = if config.channel_options.commit_upfront_shutdown_pubkey {
599599
Some(keys_provider.get_shutdown_scriptpubkey())
600-
} else {
601-
None
602-
};
600+
} else { None };
601+
602+
if let Some(shutdown_scriptpubkey) = &shutdown_scriptpubkey {
603+
if !shutdown_scriptpubkey.is_compatible(&their_features) {
604+
return Err(APIError::APIMisuseError { err: format!("Provided a scriptpubkey format not accepted by peer. script: ({})", shutdown_scriptpubkey.clone().into_inner().to_bytes().to_hex()) });
605+
}
606+
}
603607

604608
Ok(Channel {
605609
user_id,
@@ -843,14 +847,18 @@ impl<Signer: Sign> Channel<Signer> {
843847
}
844848
} else { None };
845849

846-
let mut secp_ctx = Secp256k1::new();
847-
secp_ctx.seeded_randomize(&keys_provider.get_secure_random_bytes());
848-
849850
let shutdown_scriptpubkey = if config.channel_options.commit_upfront_shutdown_pubkey {
850851
Some(keys_provider.get_shutdown_scriptpubkey())
851-
} else {
852-
None
853-
};
852+
} else { None };
853+
854+
if let Some(shutdown_scriptpubkey) = &shutdown_scriptpubkey {
855+
if !shutdown_scriptpubkey.is_compatible(&their_features) {
856+
return Err(ChannelError::Close(format!("Provided a scriptpubkey format not accepted by peer. script: ({})", shutdown_scriptpubkey.clone().into_inner().to_bytes().to_hex())));
857+
}
858+
}
859+
860+
let mut secp_ctx = Secp256k1::new();
861+
secp_ctx.seeded_randomize(&keys_provider.get_secure_random_bytes());
854862

855863
let chan = Channel {
856864
user_id,
@@ -3262,6 +3270,23 @@ impl<Signer: Sign> Channel<Signer> {
32623270
self.counterparty_shutdown_scriptpubkey = Some(shutdown_scriptpubkey);
32633271
}
32643272

3273+
// If we have any LocalAnnounced updates we'll probably just get back a update_fail_htlc
3274+
// immediately after the commitment dance, but we can send a Shutdown cause we won't send
3275+
// any further commitment updates after we set LocalShutdownSent.
3276+
let send_shutdown = (self.channel_state & ChannelState::LocalShutdownSent as u32) != ChannelState::LocalShutdownSent as u32;
3277+
3278+
let shutdown_scriptpubkey = match self.shutdown_scriptpubkey {
3279+
Some(_) => None,
3280+
None => {
3281+
assert!(send_shutdown);
3282+
let shutdown_scriptpubkey = keys_provider.get_shutdown_scriptpubkey();
3283+
if !shutdown_scriptpubkey.is_compatible(their_features) {
3284+
return Err(ChannelError::Close(format!("Provided a scriptpubkey format not accepted by peer. script: ({})", shutdown_scriptpubkey.clone().into_inner().to_bytes().to_hex())));
3285+
}
3286+
Some(shutdown_scriptpubkey)
3287+
},
3288+
};
3289+
32653290
// From here on out, we may not fail!
32663291

32673292
self.channel_state |= ChannelState::RemoteShutdownSent as u32;
@@ -3282,15 +3307,9 @@ impl<Signer: Sign> Channel<Signer> {
32823307
}
32833308
});
32843309

3285-
// If we have any LocalAnnounced updates we'll probably just get back a update_fail_htlc
3286-
// immediately after the commitment dance, but we can send a Shutdown cause we won't send
3287-
// any further commitment updates after we set LocalShutdownSent.
3288-
let send_shutdown = (self.channel_state & ChannelState::LocalShutdownSent as u32) != ChannelState::LocalShutdownSent as u32;
3289-
let monitor_update = match self.shutdown_scriptpubkey {
3290-
Some(_) => None,
3291-
None => {
3292-
assert!(send_shutdown);
3293-
self.shutdown_scriptpubkey = Some(keys_provider.get_shutdown_scriptpubkey());
3310+
let monitor_update = match shutdown_scriptpubkey {
3311+
Some(shutdown_scriptpubkey) => {
3312+
self.shutdown_scriptpubkey = Some(shutdown_scriptpubkey);
32943313
self.latest_monitor_update_id += 1;
32953314
Some(ChannelMonitorUpdate {
32963315
update_id: self.latest_monitor_update_id,
@@ -3299,6 +3318,7 @@ impl<Signer: Sign> Channel<Signer> {
32993318
}],
33003319
})
33013320
},
3321+
None => None,
33023322
};
33033323
let shutdown = if send_shutdown {
33043324
Some(msgs::Shutdown {

lightning/src/ln/channelmanager.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1156,8 +1156,13 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
11561156
return Err(APIError::APIMisuseError { err: format!("Channel value must be at least 1000 satoshis. It was {}", channel_value_satoshis) });
11571157
}
11581158

1159+
let their_features = {
1160+
let per_peer_state = self.per_peer_state.read().unwrap();
1161+
let peer_state = per_peer_state.get(&their_network_key).unwrap().lock().unwrap();
1162+
peer_state.latest_features.clone()
1163+
};
11591164
let config = if override_config.is_some() { override_config.as_ref().unwrap() } else { &self.default_configuration };
1160-
let channel = Channel::new_outbound(&self.fee_estimator, &self.keys_manager, their_network_key, channel_value_satoshis, push_msat, user_id, config)?;
1165+
let channel = Channel::new_outbound(&self.fee_estimator, &self.keys_manager, their_network_key, their_features, channel_value_satoshis, push_msat, user_id, config)?;
11611166
let res = channel.get_open_channel(self.genesis_hash.clone());
11621167

11631168
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(&self.total_consistency_lock, &self.persistence_notifier);

0 commit comments

Comments
 (0)