Skip to content

Commit b3c6926

Browse files
committed
Use ShutdownScript to check scripts from peers
1 parent 6e7a783 commit b3c6926

File tree

1 file changed

+18
-34
lines changed

1 file changed

+18
-34
lines changed

lightning/src/ln/channel.rs

Lines changed: 18 additions & 34 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;
@@ -43,11 +44,11 @@ use util::scid_utils::scid_from_parts;
4344

4445
use prelude::*;
4546
use core::{cmp,mem,fmt};
47+
use core::convert::TryFrom;
4648
use core::ops::Deref;
4749
#[cfg(any(test, feature = "fuzztarget", debug_assertions))]
4850
use sync::Mutex;
4951
use bitcoin::hashes::hex::ToHex;
50-
use bitcoin::blockdata::opcodes::all::OP_PUSHBYTES_0;
5152

5253
#[cfg(test)]
5354
pub struct ChannelValueStat {
@@ -822,11 +823,11 @@ impl<Signer: Sign> Channel<Signer> {
822823
// Peer is signaling upfront_shutdown and has opt-out with a 0-length script. We don't enforce anything
823824
if script.len() == 0 {
824825
None
825-
// Peer is signaling upfront_shutdown and has provided a non-accepted scriptpubkey format. Fail the channel
826-
} else if is_unsupported_shutdown_script(&their_features, script) {
827-
return Err(ChannelError::Close(format!("Peer is signaling upfront_shutdown but has provided a non-accepted scriptpubkey format. script: ({})", script.to_bytes().to_hex())));
828826
} else {
829-
Some(script.clone())
827+
match ShutdownScript::try_from(script.clone()) {
828+
Ok(shutdown_script) => Some(shutdown_script.into_inner()),
829+
Err(_) => return Err(ChannelError::Close(format!("Peer is signaling upfront_shutdown but has provided a non-accepted scriptpubkey format. script: ({})", script.to_bytes().to_hex()))),
830+
}
830831
}
831832
},
832833
// 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
@@ -1549,11 +1550,11 @@ impl<Signer: Sign> Channel<Signer> {
15491550
// Peer is signaling upfront_shutdown and has opt-out with a 0-length script. We don't enforce anything
15501551
if script.len() == 0 {
15511552
None
1552-
// Peer is signaling upfront_shutdown and has provided a non-accepted scriptpubkey format. Fail the channel
1553-
} else if is_unsupported_shutdown_script(&their_features, script) {
1554-
return Err(ChannelError::Close(format!("Peer is signaling upfront_shutdown but has provided a non-accepted scriptpubkey format. script: ({})", script.to_bytes().to_hex())));
15551553
} else {
1556-
Some(script.clone())
1554+
match ShutdownScript::try_from(script.clone()) {
1555+
Ok(shutdown_script) => Some(shutdown_script.into_inner()),
1556+
Err(_) => return Err(ChannelError::Close(format!("Peer is signaling upfront_shutdown but has provided a non-accepted scriptpubkey format. script: ({})", script.to_bytes().to_hex()))),
1557+
}
15571558
}
15581559
},
15591560
// 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
@@ -3209,7 +3210,7 @@ impl<Signer: Sign> Channel<Signer> {
32093210
})
32103211
}
32113212

3212-
pub fn shutdown<F: Deref>(&mut self, fee_estimator: &F, their_features: &InitFeatures, msg: &msgs::Shutdown) -> Result<(Option<msgs::Shutdown>, Option<msgs::ClosingSigned>, Vec<(HTLCSource, PaymentHash)>), ChannelError>
3213+
pub fn shutdown<F: Deref>(&mut self, fee_estimator: &F, _their_features: &InitFeatures, msg: &msgs::Shutdown) -> Result<(Option<msgs::Shutdown>, Option<msgs::ClosingSigned>, Vec<(HTLCSource, PaymentHash)>), ChannelError>
32133214
where F::Target: FeeEstimator
32143215
{
32153216
if self.channel_state & (ChannelState::PeerDisconnected as u32) == ChannelState::PeerDisconnected as u32 {
@@ -3228,16 +3229,17 @@ impl<Signer: Sign> Channel<Signer> {
32283229
}
32293230
assert_eq!(self.channel_state & ChannelState::ShutdownComplete as u32, 0);
32303231

3231-
if is_unsupported_shutdown_script(&their_features, &msg.scriptpubkey) {
3232-
return Err(ChannelError::Close(format!("Got a nonstandard scriptpubkey ({}) from remote peer", msg.scriptpubkey.to_bytes().to_hex())));
3233-
}
3232+
let shutdown_scriptpubkey = match ShutdownScript::try_from(msg.scriptpubkey.clone()) {
3233+
Ok(script) => script.into_inner(),
3234+
Err(_) => return Err(ChannelError::Close(format!("Got a nonstandard scriptpubkey ({}) from remote peer", msg.scriptpubkey.to_bytes().to_hex()))),
3235+
};
32343236

32353237
if self.counterparty_shutdown_scriptpubkey.is_some() {
3236-
if Some(&msg.scriptpubkey) != self.counterparty_shutdown_scriptpubkey.as_ref() {
3237-
return Err(ChannelError::Close(format!("Got shutdown request with a scriptpubkey ({}) which did not match their previous scriptpubkey.", msg.scriptpubkey.to_bytes().to_hex())));
3238+
if Some(&shutdown_scriptpubkey) != self.counterparty_shutdown_scriptpubkey.as_ref() {
3239+
return Err(ChannelError::Close(format!("Got shutdown request with a scriptpubkey ({}) which did not match their previous scriptpubkey.", shutdown_scriptpubkey.to_bytes().to_hex())));
32383240
}
32393241
} else {
3240-
self.counterparty_shutdown_scriptpubkey = Some(msg.scriptpubkey.clone());
3242+
self.counterparty_shutdown_scriptpubkey = Some(shutdown_scriptpubkey);
32413243
}
32423244

32433245
// From here on out, we may not fail!
@@ -4484,24 +4486,6 @@ impl<Signer: Sign> Channel<Signer> {
44844486
}
44854487
}
44864488

4487-
fn is_unsupported_shutdown_script(their_features: &InitFeatures, script: &Script) -> bool {
4488-
// We restrain shutdown scripts to standards forms to avoid transactions not propagating on the p2p tx-relay network
4489-
4490-
// BOLT 2 says we must only send a scriptpubkey of certain standard forms,
4491-
// which for a a BIP-141-compliant witness program is at max 42 bytes in length.
4492-
// So don't let the remote peer feed us some super fee-heavy script.
4493-
let is_script_too_long = script.len() > 42;
4494-
if is_script_too_long {
4495-
return true;
4496-
}
4497-
4498-
if their_features.supports_shutdown_anysegwit() && script.is_witness_program() && script.as_bytes()[0] != OP_PUSHBYTES_0.into_u8() {
4499-
return false;
4500-
}
4501-
4502-
return !script.is_p2pkh() && !script.is_p2sh() && !script.is_v0_p2wpkh() && !script.is_v0_p2wsh()
4503-
}
4504-
45054489
const SERIALIZATION_VERSION: u8 = 2;
45064490
const MIN_SERIALIZATION_VERSION: u8 = 1;
45074491

0 commit comments

Comments
 (0)