Skip to content

Commit 9377b16

Browse files
committed
Use ShutdownScript to check scripts from peers
1 parent ce27553 commit 9377b16

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;
@@ -44,10 +45,10 @@ use util::scid_utils::scid_from_parts;
4445
use prelude::*;
4546
use core::{cmp,mem,fmt};
4647
use core::ops::Deref;
48+
use std::convert::TryFrom;
4749
#[cfg(any(test, feature = "fuzztarget"))]
4850
use std::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 {
@@ -783,11 +784,11 @@ impl<Signer: Sign> Channel<Signer> {
783784
// Peer is signaling upfront_shutdown and has opt-out with a 0-length script. We don't enforce anything
784785
if script.len() == 0 {
785786
None
786-
// Peer is signaling upfront_shutdown and has provided a non-accepted scriptpubkey format. Fail the channel
787-
} else if is_unsupported_shutdown_script(&their_features, script) {
788-
return Err(ChannelError::Close(format!("Peer is signaling upfront_shutdown but has provided a non-accepted scriptpubkey format. script: ({})", script.to_bytes().to_hex())));
789787
} else {
790-
Some(script.clone())
788+
match ShutdownScript::try_from(script.clone()) {
789+
Ok(shutdown_script) => Some(shutdown_script.into_inner()),
790+
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()))),
791+
}
791792
}
792793
},
793794
// 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
@@ -1494,11 +1495,11 @@ impl<Signer: Sign> Channel<Signer> {
14941495
// Peer is signaling upfront_shutdown and has opt-out with a 0-length script. We don't enforce anything
14951496
if script.len() == 0 {
14961497
None
1497-
// Peer is signaling upfront_shutdown and has provided a non-accepted scriptpubkey format. Fail the channel
1498-
} else if is_unsupported_shutdown_script(&their_features, script) {
1499-
return Err(ChannelError::Close(format!("Peer is signaling upfront_shutdown but has provided a non-accepted scriptpubkey format. script: ({})", script.to_bytes().to_hex())));
15001498
} else {
1501-
Some(script.clone())
1499+
match ShutdownScript::try_from(script.clone()) {
1500+
Ok(shutdown_script) => Some(shutdown_script.into_inner()),
1501+
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()))),
1502+
}
15021503
}
15031504
},
15041505
// 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
@@ -3150,7 +3151,7 @@ impl<Signer: Sign> Channel<Signer> {
31503151
})
31513152
}
31523153

3153-
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>
3154+
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>
31543155
where F::Target: FeeEstimator
31553156
{
31563157
if self.channel_state & (ChannelState::PeerDisconnected as u32) == ChannelState::PeerDisconnected as u32 {
@@ -3169,16 +3170,17 @@ impl<Signer: Sign> Channel<Signer> {
31693170
}
31703171
assert_eq!(self.channel_state & ChannelState::ShutdownComplete as u32, 0);
31713172

3172-
if is_unsupported_shutdown_script(&their_features, &msg.scriptpubkey) {
3173-
return Err(ChannelError::Close(format!("Got a nonstandard scriptpubkey ({}) from remote peer", msg.scriptpubkey.to_bytes().to_hex())));
3174-
}
3173+
let shutdown_scriptpubkey = match ShutdownScript::try_from(msg.scriptpubkey.clone()) {
3174+
Ok(script) => script.into_inner(),
3175+
Err(_) => return Err(ChannelError::Close(format!("Got a nonstandard scriptpubkey ({}) from remote peer", msg.scriptpubkey.to_bytes().to_hex()))),
3176+
};
31753177

31763178
if self.counterparty_shutdown_scriptpubkey.is_some() {
3177-
if Some(&msg.scriptpubkey) != self.counterparty_shutdown_scriptpubkey.as_ref() {
3178-
return Err(ChannelError::Close(format!("Got shutdown request with a scriptpubkey ({}) which did not match their previous scriptpubkey.", msg.scriptpubkey.to_bytes().to_hex())));
3179+
if Some(&shutdown_scriptpubkey) != self.counterparty_shutdown_scriptpubkey.as_ref() {
3180+
return Err(ChannelError::Close(format!("Got shutdown request with a scriptpubkey ({}) which did not match their previous scriptpubkey.", shutdown_scriptpubkey.to_bytes().to_hex())));
31793181
}
31803182
} else {
3181-
self.counterparty_shutdown_scriptpubkey = Some(msg.scriptpubkey.clone());
3183+
self.counterparty_shutdown_scriptpubkey = Some(shutdown_scriptpubkey);
31823184
}
31833185

31843186
// From here on out, we may not fail!
@@ -4425,24 +4427,6 @@ impl<Signer: Sign> Channel<Signer> {
44254427
}
44264428
}
44274429

4428-
fn is_unsupported_shutdown_script(their_features: &InitFeatures, script: &Script) -> bool {
4429-
// We restrain shutdown scripts to standards forms to avoid transactions not propagating on the p2p tx-relay network
4430-
4431-
// BOLT 2 says we must only send a scriptpubkey of certain standard forms,
4432-
// which for a a BIP-141-compliant witness program is at max 42 bytes in length.
4433-
// So don't let the remote peer feed us some super fee-heavy script.
4434-
let is_script_too_long = script.len() > 42;
4435-
if is_script_too_long {
4436-
return true;
4437-
}
4438-
4439-
if their_features.supports_shutdown_anysegwit() && script.is_witness_program() && script.as_bytes()[0] != OP_PUSHBYTES_0.into_u8() {
4440-
return false;
4441-
}
4442-
4443-
return !script.is_p2pkh() && !script.is_p2sh() && !script.is_v0_p2wpkh() && !script.is_v0_p2wsh()
4444-
}
4445-
44464430
const SERIALIZATION_VERSION: u8 = 2;
44474431
const MIN_SERIALIZATION_VERSION: u8 = 1;
44484432

0 commit comments

Comments
 (0)