Skip to content

Commit 1ab2c7c

Browse files
committed
Use ShutdownScript to check scripts from peers
1 parent ecc7075 commit 1ab2c7c

File tree

2 files changed

+20
-36
lines changed

2 files changed

+20
-36
lines changed

lightning/src/ln/channel.rs

Lines changed: 17 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ use ln::{PaymentPreimage, PaymentHash};
2626
use ln::features::{ChannelFeatures, InitFeatures};
2727
use ln::msgs;
2828
use ln::msgs::{DecodeError, OptionalField, DataLossProtect};
29+
use ln::script::ShutdownScript;
2930
use ln::channelmanager::{PendingHTLCStatus, HTLCSource, HTLCFailReason, HTLCFailureMsg, PendingHTLCInfo, RAACommitmentOrder, BREAKDOWN_TIMEOUT, MIN_CLTV_EXPIRY_DELTA, MAX_LOCAL_BREAKDOWN_TIMEOUT};
3031
use ln::chan_utils::{CounterpartyCommitmentSecrets, TxCreationKeys, HTLCOutputInCommitment, HTLC_SUCCESS_TX_WEIGHT, HTLC_TIMEOUT_TX_WEIGHT, make_funding_redeemscript, ChannelPublicKeys, CommitmentTransaction, HolderCommitmentTransaction, ChannelTransactionParameters, CounterpartyChannelTransactionParameters, MAX_HTLCS, get_commitment_transaction_number_obscure_factor};
3132
use ln::chan_utils;
@@ -44,11 +45,11 @@ use util::scid_utils::scid_from_parts;
4445
use io;
4546
use prelude::*;
4647
use core::{cmp,mem,fmt};
48+
use core::convert::TryFrom;
4749
use core::ops::Deref;
4850
#[cfg(any(test, feature = "fuzztarget", debug_assertions))]
4951
use sync::Mutex;
5052
use bitcoin::hashes::hex::ToHex;
51-
use bitcoin::blockdata::opcodes::all::OP_PUSHBYTES_0;
5253

5354
#[cfg(test)]
5455
pub struct ChannelValueStat {
@@ -829,11 +830,11 @@ impl<Signer: Sign> Channel<Signer> {
829830
// Peer is signaling upfront_shutdown and has opt-out with a 0-length script. We don't enforce anything
830831
if script.len() == 0 {
831832
None
832-
// Peer is signaling upfront_shutdown and has provided a non-accepted scriptpubkey format. Fail the channel
833-
} else if is_unsupported_shutdown_script(&their_features, script) {
834-
return Err(ChannelError::Close(format!("Peer is signaling upfront_shutdown but has provided a non-accepted scriptpubkey format. script: ({})", script.to_bytes().to_hex())));
835833
} else {
836-
Some(script.clone())
834+
match ShutdownScript::try_from((script.clone(), &their_features)) {
835+
Ok(shutdown_script) => Some(shutdown_script.into_inner()),
836+
Err(_) => return Err(ChannelError::Close(format!("Peer is signaling upfront_shutdown but has provided an unacceptable scriptpubkey format. script: ({})", script.to_bytes().to_hex()))),
837+
}
837838
}
838839
},
839840
// 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
@@ -1560,11 +1561,11 @@ impl<Signer: Sign> Channel<Signer> {
15601561
// Peer is signaling upfront_shutdown and has opt-out with a 0-length script. We don't enforce anything
15611562
if script.len() == 0 {
15621563
None
1563-
// Peer is signaling upfront_shutdown and has provided a non-accepted scriptpubkey format. Fail the channel
1564-
} else if is_unsupported_shutdown_script(&their_features, script) {
1565-
return Err(ChannelError::Close(format!("Peer is signaling upfront_shutdown but has provided a non-accepted scriptpubkey format. script: ({})", script.to_bytes().to_hex())));
15661564
} else {
1567-
Some(script.clone())
1565+
match ShutdownScript::try_from((script.clone(), &their_features)) {
1566+
Ok(shutdown_script) => Some(shutdown_script.into_inner()),
1567+
Err(_) => return Err(ChannelError::Close(format!("Peer is signaling upfront_shutdown but has provided an unacceptable scriptpubkey format. script: ({})", script.to_bytes().to_hex()))),
1568+
}
15681569
}
15691570
},
15701571
// 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
@@ -3239,16 +3240,17 @@ impl<Signer: Sign> Channel<Signer> {
32393240
}
32403241
assert_eq!(self.channel_state & ChannelState::ShutdownComplete as u32, 0);
32413242

3242-
if is_unsupported_shutdown_script(&their_features, &msg.scriptpubkey) {
3243-
return Err(ChannelError::Close(format!("Got a nonstandard scriptpubkey ({}) from remote peer", msg.scriptpubkey.to_bytes().to_hex())));
3244-
}
3243+
let shutdown_scriptpubkey = match ShutdownScript::try_from((msg.scriptpubkey.clone(), their_features)) {
3244+
Ok(script) => script.into_inner(),
3245+
Err(_) => return Err(ChannelError::Close(format!("Got a nonstandard scriptpubkey ({}) from remote peer", msg.scriptpubkey.to_bytes().to_hex()))),
3246+
};
32453247

32463248
if self.counterparty_shutdown_scriptpubkey.is_some() {
3247-
if Some(&msg.scriptpubkey) != self.counterparty_shutdown_scriptpubkey.as_ref() {
3248-
return Err(ChannelError::Close(format!("Got shutdown request with a scriptpubkey ({}) which did not match their previous scriptpubkey.", msg.scriptpubkey.to_bytes().to_hex())));
3249+
if Some(&shutdown_scriptpubkey) != self.counterparty_shutdown_scriptpubkey.as_ref() {
3250+
return Err(ChannelError::Close(format!("Got shutdown request with a scriptpubkey ({}) which did not match their previous scriptpubkey.", shutdown_scriptpubkey.to_bytes().to_hex())));
32493251
}
32503252
} else {
3251-
self.counterparty_shutdown_scriptpubkey = Some(msg.scriptpubkey.clone());
3253+
self.counterparty_shutdown_scriptpubkey = Some(shutdown_scriptpubkey);
32523254
}
32533255

32543256
// From here on out, we may not fail!
@@ -4495,24 +4497,6 @@ impl<Signer: Sign> Channel<Signer> {
44954497
}
44964498
}
44974499

4498-
fn is_unsupported_shutdown_script(their_features: &InitFeatures, script: &Script) -> bool {
4499-
// We restrain shutdown scripts to standards forms to avoid transactions not propagating on the p2p tx-relay network
4500-
4501-
// BOLT 2 says we must only send a scriptpubkey of certain standard forms,
4502-
// which for a a BIP-141-compliant witness program is at max 42 bytes in length.
4503-
// So don't let the remote peer feed us some super fee-heavy script.
4504-
let is_script_too_long = script.len() > 42;
4505-
if is_script_too_long {
4506-
return true;
4507-
}
4508-
4509-
if their_features.supports_shutdown_anysegwit() && script.is_witness_program() && script.as_bytes()[0] != OP_PUSHBYTES_0.into_u8() {
4510-
return false;
4511-
}
4512-
4513-
return !script.is_p2pkh() && !script.is_p2sh() && !script.is_v0_p2wpkh() && !script.is_v0_p2wsh()
4514-
}
4515-
45164500
const SERIALIZATION_VERSION: u8 = 2;
45174501
const MIN_SERIALIZATION_VERSION: u8 = 1;
45184502

lightning/src/ln/functional_tests.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7545,7 +7545,7 @@ fn test_unsupported_anysegwit_upfront_shutdown_script() {
75457545
match events[0] {
75467546
MessageSendEvent::HandleError { action: ErrorAction::SendErrorMessage { ref msg }, node_id } => {
75477547
assert_eq!(node_id, nodes[0].node.get_our_node_id());
7548-
assert!(regex::Regex::new(r"Peer is signaling upfront_shutdown but has provided a non-accepted scriptpubkey format. script: (\([A-Fa-f0-9]+\))").unwrap().is_match(&*msg.data));
7548+
assert!(regex::Regex::new(r"Peer is signaling upfront_shutdown but has provided an unacceptable scriptpubkey format. script: (\([A-Fa-f0-9]+\))").unwrap().is_match(&*msg.data));
75497549
},
75507550
_ => panic!("Unexpected event"),
75517551
}
@@ -7563,7 +7563,7 @@ fn test_unsupported_anysegwit_upfront_shutdown_script() {
75637563
match events[0] {
75647564
MessageSendEvent::HandleError { action: ErrorAction::SendErrorMessage { ref msg }, node_id } => {
75657565
assert_eq!(node_id, nodes[1].node.get_our_node_id());
7566-
assert!(regex::Regex::new(r"Peer is signaling upfront_shutdown but has provided a non-accepted scriptpubkey format. script: (\([A-Fa-f0-9]+\))").unwrap().is_match(&*msg.data));
7566+
assert!(regex::Regex::new(r"Peer is signaling upfront_shutdown but has provided an unacceptable scriptpubkey format. script: (\([A-Fa-f0-9]+\))").unwrap().is_match(&*msg.data));
75677567
},
75687568
_ => panic!("Unexpected event"),
75697569
}
@@ -7590,7 +7590,7 @@ fn test_invalid_upfront_shutdown_script() {
75907590
match events[0] {
75917591
MessageSendEvent::HandleError { action: ErrorAction::SendErrorMessage { ref msg }, node_id } => {
75927592
assert_eq!(node_id, nodes[0].node.get_our_node_id());
7593-
assert!(regex::Regex::new(r"Peer is signaling upfront_shutdown but has provided a non-accepted scriptpubkey format. script: (\([A-Fa-f0-9]+\))").unwrap().is_match(&*msg.data));
7593+
assert!(regex::Regex::new(r"Peer is signaling upfront_shutdown but has provided an unacceptable scriptpubkey format. script: (\([A-Fa-f0-9]+\))").unwrap().is_match(&*msg.data));
75947594
},
75957595
_ => panic!("Unexpected event"),
75967596
}

0 commit comments

Comments
 (0)