@@ -45,6 +45,7 @@ use std::ops::Deref;
4545#[ cfg( any( test, feature = "fuzztarget" ) ) ]
4646use std:: sync:: Mutex ;
4747use bitcoin:: hashes:: hex:: ToHex ;
48+ use bitcoin:: blockdata:: opcodes:: all:: OP_PUSHBYTES_0 ;
4849
4950#[ cfg( test) ]
5051pub struct ChannelValueStat {
@@ -737,15 +738,14 @@ impl<Signer: Sign> Channel<Signer> {
737738 let counterparty_shutdown_scriptpubkey = if their_features. supports_upfront_shutdown_script ( ) {
738739 match & msg. shutdown_scriptpubkey {
739740 & 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 ( ) )
743741 // 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 {
745743 None
746744 // 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 ) {
748746 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 ( ) )
749749 }
750750 } ,
751751 // 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> {
14391439 let counterparty_shutdown_scriptpubkey = if their_features. supports_upfront_shutdown_script ( ) {
14401440 match & msg. shutdown_scriptpubkey {
14411441 & 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 ( ) )
14451442 // 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 {
14471444 None
14481445 // 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( ) ) ) ) ;
14491448 } 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 ( ) )
14511450 }
14521451 } ,
14531452 // 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> {
30663065 } )
30673066 }
30683067
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 >
30703069 where F :: Target : FeeEstimator
30713070 {
30723071 if self . channel_state & ( ChannelState :: PeerDisconnected as u32 ) == ChannelState :: PeerDisconnected as u32 {
@@ -3085,14 +3084,7 @@ impl<Signer: Sign> Channel<Signer> {
30853084 }
30863085 assert_eq ! ( self . channel_state & ChannelState :: ShutdownComplete as u32 , 0 ) ;
30873086
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 ) {
30963088 return Err ( ChannelError :: Close ( format ! ( "Got a nonstandard scriptpubkey ({}) from remote peer" , msg. scriptpubkey. to_bytes( ) . to_hex( ) ) ) ) ;
30973089 }
30983090
@@ -4217,6 +4209,24 @@ impl<Signer: Sign> Channel<Signer> {
42174209 }
42184210}
42194211
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+
42204230const SERIALIZATION_VERSION : u8 = 1 ;
42214231const MIN_SERIALIZATION_VERSION : u8 = 1 ;
42224232
0 commit comments