@@ -45,6 +45,7 @@ use std::ops::Deref;
45
45
#[ cfg( any( test, feature = "fuzztarget" ) ) ]
46
46
use std:: sync:: Mutex ;
47
47
use bitcoin:: hashes:: hex:: ToHex ;
48
+ use bitcoin:: blockdata:: opcodes:: all:: OP_PUSHBYTES_0 ;
48
49
49
50
#[ cfg( test) ]
50
51
pub struct ChannelValueStat {
@@ -737,15 +738,14 @@ impl<Signer: Sign> Channel<Signer> {
737
738
let counterparty_shutdown_scriptpubkey = if their_features. supports_upfront_shutdown_script ( ) {
738
739
match & msg. shutdown_scriptpubkey {
739
740
& OptionalField :: Present ( ref script) => {
740
- // Peer is signaling upfront_shutdown and has provided a non-accepted scriptpubkey format. We enforce it while receiving shutdown msg
741
- if script. is_p2pkh ( ) || script. is_p2sh ( ) || script. is_v0_p2wsh ( ) || script. is_v0_p2wpkh ( ) {
742
- Some ( script. clone ( ) )
743
741
// Peer is signaling upfront_shutdown and has opt-out with a 0-length script. We don't enforce anything
744
- } else if script. len ( ) == 0 {
742
+ if script. len ( ) == 0 {
745
743
None
746
744
// Peer is signaling upfront_shutdown and has provided a non-accepted scriptpubkey format. Fail the channel
747
- } else {
745
+ } else if is_unsupported_shutdown_script ( & their_features , script ) {
748
746
return Err ( ChannelError :: Close ( format ! ( "Peer is signaling upfront_shutdown but has provided a non-accepted scriptpubkey format. script: ({})" , script. to_bytes( ) . to_hex( ) ) ) ) ;
747
+ } else {
748
+ Some ( script. clone ( ) )
749
749
}
750
750
} ,
751
751
// 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,15 +1439,14 @@ impl<Signer: Sign> Channel<Signer> {
1439
1439
let counterparty_shutdown_scriptpubkey = if their_features. supports_upfront_shutdown_script ( ) {
1440
1440
match & msg. shutdown_scriptpubkey {
1441
1441
& OptionalField :: Present ( ref script) => {
1442
- // Peer is signaling upfront_shutdown and has provided a non-accepted scriptpubkey format. We enforce it while receiving shutdown msg
1443
- if script. is_p2pkh ( ) || script. is_p2sh ( ) || script. is_v0_p2wsh ( ) || script. is_v0_p2wpkh ( ) {
1444
- Some ( script. clone ( ) )
1445
1442
// Peer is signaling upfront_shutdown and has opt-out with a 0-length script. We don't enforce anything
1446
- } else if script. len ( ) == 0 {
1443
+ if script. len ( ) == 0 {
1447
1444
None
1448
1445
// Peer is signaling upfront_shutdown and has provided a non-accepted scriptpubkey format. Fail the channel
1446
+ } else if is_unsupported_shutdown_script ( & their_features, script) {
1447
+ return Err ( ChannelError :: Close ( format ! ( "Peer is signaling upfront_shutdown but has provided a non-accepted scriptpubkey format. script: ({})" , script. to_bytes( ) . to_hex( ) ) ) ) ;
1449
1448
} else {
1450
- return Err ( ChannelError :: Close ( format ! ( "Peer is signaling upfront_shutdown but has provided a non-accepted scriptpubkey format. scriptpubkey: ({})" , script. to_bytes ( ) . to_hex ( ) ) ) ) ;
1449
+ Some ( script. clone ( ) )
1451
1450
}
1452
1451
} ,
1453
1452
// 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
@@ -3066,7 +3065,7 @@ impl<Signer: Sign> Channel<Signer> {
3066
3065
} )
3067
3066
}
3068
3067
3069
- pub fn shutdown < F : Deref > ( & mut self , fee_estimator : & F , msg : & msgs:: Shutdown ) -> Result < ( Option < msgs:: Shutdown > , Option < msgs:: ClosingSigned > , Vec < ( HTLCSource , PaymentHash ) > ) , ChannelError >
3068
+ 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 >
3070
3069
where F :: Target : FeeEstimator
3071
3070
{
3072
3071
if self . channel_state & ( ChannelState :: PeerDisconnected as u32 ) == ChannelState :: PeerDisconnected as u32 {
@@ -3085,14 +3084,7 @@ impl<Signer: Sign> Channel<Signer> {
3085
3084
}
3086
3085
assert_eq ! ( self . channel_state & ChannelState :: ShutdownComplete as u32 , 0 ) ;
3087
3086
3088
- // BOLT 2 says we must only send a scriptpubkey of certain standard forms, which are up to
3089
- // 34 bytes in length, so don't let the remote peer feed us some super fee-heavy script.
3090
- if self . is_outbound ( ) && msg. scriptpubkey . len ( ) > 34 {
3091
- return Err ( ChannelError :: Close ( format ! ( "Got counterparty shutdown_scriptpubkey ({}) of absurd length from remote peer" , msg. scriptpubkey. to_bytes( ) . to_hex( ) ) ) ) ;
3092
- }
3093
-
3094
- //Check counterparty_shutdown_scriptpubkey form as BOLT says we must
3095
- if !msg. scriptpubkey . is_p2pkh ( ) && !msg. scriptpubkey . is_p2sh ( ) && !msg. scriptpubkey . is_v0_p2wpkh ( ) && !msg. scriptpubkey . is_v0_p2wsh ( ) {
3087
+ if is_unsupported_shutdown_script ( & their_features, & msg. scriptpubkey ) {
3096
3088
return Err ( ChannelError :: Close ( format ! ( "Got a nonstandard scriptpubkey ({}) from remote peer" , msg. scriptpubkey. to_bytes( ) . to_hex( ) ) ) ) ;
3097
3089
}
3098
3090
@@ -4217,6 +4209,24 @@ impl<Signer: Sign> Channel<Signer> {
4217
4209
}
4218
4210
}
4219
4211
4212
+ fn is_unsupported_shutdown_script ( their_features : & InitFeatures , script : & Script ) -> bool {
4213
+ // We restrain shutdown scripts to standards forms to avoid transactions not propagating on the p2p tx-relay network
4214
+
4215
+ // BOLT 2 says we must only send a scriptpubkey of certain standard forms,
4216
+ // which for a a BIP-141-compliant witness program is at max 42 bytes in length.
4217
+ // So don't let the remote peer feed us some super fee-heavy script.
4218
+ let is_script_too_long = script. len ( ) > 42 ;
4219
+ if is_script_too_long {
4220
+ return true ;
4221
+ }
4222
+
4223
+ if their_features. supports_shutdown_anysegwit ( ) && script. is_witness_program ( ) && script. as_bytes ( ) [ 0 ] != OP_PUSHBYTES_0 . into_u8 ( ) {
4224
+ return false ;
4225
+ }
4226
+
4227
+ return !script. is_p2pkh ( ) && !script. is_p2sh ( ) && !script. is_v0_p2wpkh ( ) && !script. is_v0_p2wsh ( )
4228
+ }
4229
+
4220
4230
const SERIALIZATION_VERSION : u8 = 1 ;
4221
4231
const MIN_SERIALIZATION_VERSION : u8 = 1 ;
4222
4232
0 commit comments