Skip to content

Commit 675cf4a

Browse files
author
Antoine Riard
committed
Support option_upfront_shutdown_script for local peer
Track shutdown_pubkey of peer at open/accept_channel messages Fix encoding_init test
1 parent 0052b2c commit 675cf4a

File tree

3 files changed

+58
-12
lines changed

3 files changed

+58
-12
lines changed

src/ln/channel.rs

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -522,7 +522,7 @@ impl Channel {
522522

523523
/// Creates a new channel from a remote sides' request for one.
524524
/// Assumes chain_hash has already been checked and corresponds with what we expect!
525-
pub fn new_from_req(fee_estimator: &FeeEstimator, keys_provider: &Arc<KeysInterface>, their_node_id: PublicKey, _their_local_features: LocalFeatures, msg: &msgs::OpenChannel, user_id: u64, logger: Arc<Logger>, config: &UserConfig) -> Result<Channel, ChannelError> {
525+
pub fn new_from_req(fee_estimator: &FeeEstimator, keys_provider: &Arc<KeysInterface>, their_node_id: PublicKey, their_local_features: LocalFeatures, msg: &msgs::OpenChannel, user_id: u64, logger: Arc<Logger>, config: &UserConfig) -> Result<Channel, ChannelError> {
526526
let chan_keys = keys_provider.get_channel_keys(true);
527527
let mut local_config = (*config).channel_options.clone();
528528

@@ -625,6 +625,27 @@ impl Channel {
625625
channel_monitor.set_their_base_keys(&msg.htlc_basepoint, &msg.delayed_payment_basepoint);
626626
channel_monitor.set_their_to_self_delay(msg.to_self_delay);
627627

628+
let their_shutdown_scriptpubkey = if their_local_features.supports_upfront_shutdown_script() {
629+
match &msg.shutdown_scriptpubkey {
630+
&OptionalField::Present(ref script) => {
631+
// Peer is signaling upfront_shutdown and has provided a non-accepted scriptpubkey format. We enforce it while receiving shutdown msg
632+
if script.is_p2pkh() || script.is_p2sh() || script.is_v0_p2wsh() || script.is_v0_p2wpkh() {
633+
Some(script.clone())
634+
// Peer is signaling upfront_shutdown and has opt-out with a 0-length script. We don't enforce anything
635+
} else if script.len() == 0 {
636+
None
637+
// Peer is signaling upfront_shutdown and has provided a non-accepted scriptpubkey format. Fail the channel
638+
} else {
639+
return Err(ChannelError::Close("Peer is signaling upfront_shutdown but has provided a non-accepted scriptpubkey format"));
640+
}
641+
},
642+
// 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
643+
&OptionalField::Absent => {
644+
return Err(ChannelError::Close("Peer is signaling upfront_shutdown but we don't get any script. Use 0-length script to opt-out"));
645+
}
646+
}
647+
} else { None };
648+
628649
let mut chan = Channel {
629650
user_id: user_id,
630651
config: local_config,
@@ -692,7 +713,7 @@ impl Channel {
692713
their_prev_commitment_point: None,
693714
their_node_id: their_node_id,
694715

695-
their_shutdown_scriptpubkey: None,
716+
their_shutdown_scriptpubkey,
696717

697718
channel_monitor: channel_monitor,
698719

@@ -1341,7 +1362,7 @@ impl Channel {
13411362

13421363
// Message handlers:
13431364

1344-
pub fn accept_channel(&mut self, msg: &msgs::AcceptChannel, config: &UserConfig, _their_local_features: LocalFeatures) -> Result<(), ChannelError> {
1365+
pub fn accept_channel(&mut self, msg: &msgs::AcceptChannel, config: &UserConfig, their_local_features: LocalFeatures) -> Result<(), ChannelError> {
13451366
// Check sanity of message fields:
13461367
if !self.channel_outbound {
13471368
return Err(ChannelError::Close("Got an accept_channel message from an inbound peer"));
@@ -1400,6 +1421,27 @@ impl Channel {
14001421
return Err(ChannelError::Close("We consider the minimum depth to be unreasonably large"));
14011422
}
14021423

1424+
let their_shutdown_scriptpubkey = if their_local_features.supports_upfront_shutdown_script() {
1425+
match &msg.shutdown_scriptpubkey {
1426+
&OptionalField::Present(ref script) => {
1427+
// Peer is signaling upfront_shutdown and has provided a non-accepted scriptpubkey format. We enforce it while receiving shutdown msg
1428+
if script.is_p2pkh() || script.is_p2sh() || script.is_v0_p2wsh() || script.is_v0_p2wpkh() {
1429+
Some(script.clone())
1430+
// Peer is signaling upfront_shutdown and has opt-out with a 0-length script. We don't enforce anything
1431+
} else if script.len() == 0 {
1432+
None
1433+
// Peer is signaling upfront_shutdown and has provided a non-accepted scriptpubkey format. Fail the channel
1434+
} else {
1435+
return Err(ChannelError::Close("Peer is signaling upfront_shutdown but has provided a non-accepted scriptpubkey format"));
1436+
}
1437+
},
1438+
// 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
1439+
&OptionalField::Absent => {
1440+
return Err(ChannelError::Close("Peer is signaling upfront_shutdown but we don't get any script. Use 0-length script to opt-out"));
1441+
}
1442+
}
1443+
} else { None };
1444+
14031445
self.channel_monitor.set_their_base_keys(&msg.htlc_basepoint, &msg.delayed_payment_basepoint);
14041446

14051447
self.their_dust_limit_satoshis = msg.dust_limit_satoshis;
@@ -1415,6 +1457,7 @@ impl Channel {
14151457
self.their_delayed_payment_basepoint = Some(msg.delayed_payment_basepoint);
14161458
self.their_htlc_basepoint = Some(msg.htlc_basepoint);
14171459
self.their_cur_commitment_point = Some(msg.first_per_commitment_point);
1460+
self.their_shutdown_scriptpubkey = their_shutdown_scriptpubkey;
14181461

14191462
let obscure_factor = self.get_commitment_transaction_number_obscure_factor();
14201463
self.channel_monitor.set_commitment_obscure_factor(obscure_factor);

src/ln/msgs.rs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,16 @@ pub struct LocalFeatures {
6060

6161
impl LocalFeatures {
6262
/// Create a blank LocalFeatures flags (visibility extended for fuzz tests)
63+
#[cfg(not(feature = "fuzztarget"))]
64+
pub(crate) fn new() -> LocalFeatures {
65+
LocalFeatures {
66+
flags: vec![1 << 4],
67+
}
68+
}
69+
#[cfg(feature = "fuzztarget")]
6370
pub fn new() -> LocalFeatures {
6471
LocalFeatures {
65-
flags: Vec::new(),
72+
flags: vec![1 << 4],
6673
}
6774
}
6875

@@ -87,8 +94,8 @@ impl LocalFeatures {
8794
pub(crate) fn supports_upfront_shutdown_script(&self) -> bool {
8895
self.flags.len() > 0 && (self.flags[0] & (3 << 4)) != 0
8996
}
90-
pub(crate) fn requires_upfront_shutdown_script(&self) -> bool {
91-
self.flags.len() > 0 && (self.flags[0] & (1 << 4)) != 0
97+
pub(crate) fn unset_upfront_shutdown_script(&mut self) {
98+
self.flags[0] ^= 1 << 4;
9299
}
93100

94101
pub(crate) fn requires_unknown_bits(&self) -> bool {
@@ -2011,9 +2018,9 @@ mod tests {
20112018
target_value.append(&mut hex::decode("0000").unwrap());
20122019
}
20132020
if initial_routing_sync {
2014-
target_value.append(&mut hex::decode("000108").unwrap());
2021+
target_value.append(&mut hex::decode("000118").unwrap());
20152022
} else {
2016-
target_value.append(&mut hex::decode("0000").unwrap());
2023+
target_value.append(&mut hex::decode("000110").unwrap());
20172024
}
20182025
assert_eq!(encoded_value, target_value);
20192026
}

src/ln/peer_handler.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -587,10 +587,6 @@ impl<Descriptor: SocketDescriptor> PeerManager<Descriptor> {
587587
log_info!(self, "Peer local features required data_loss_protect");
588588
return Err(PeerHandleError{ no_connection_possible: true });
589589
}
590-
if msg.local_features.requires_upfront_shutdown_script() {
591-
log_info!(self, "Peer local features required upfront_shutdown_script");
592-
return Err(PeerHandleError{ no_connection_possible: true });
593-
}
594590
if peer.their_global_features.is_some() {
595591
return Err(PeerHandleError{ no_connection_possible: false });
596592
}

0 commit comments

Comments
 (0)