Skip to content

Commit 99ee676

Browse files
committed
f - Add ShutdownScript::is_compatible
1 parent 1e922ae commit 99ee676

File tree

1 file changed

+52
-4
lines changed

1 file changed

+52
-4
lines changed

lightning/src/ln/script.rs

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,26 @@ impl ShutdownScript {
105105
ShutdownScriptImpl::Bolt2(_) => None,
106106
}
107107
}
108+
109+
/// Returns whether the shutdown script is compatible with the features as defined by BOLT #2.
110+
///
111+
/// Specifically, checks for compliance with feature `option_shutdown_anysegwit`.
112+
pub fn is_compatible(&self, features: &InitFeatures) -> bool {
113+
match &self.0 {
114+
ShutdownScriptImpl::Legacy(_) => true,
115+
ShutdownScriptImpl::Bolt2(script) => is_bolt2_compliant(script, features),
116+
}
117+
}
118+
}
119+
120+
fn is_bolt2_compliant(script: &Script, features: &InitFeatures) -> bool {
121+
if script.is_p2pkh() || script.is_p2sh() || script.is_v0_p2wpkh() || script.is_v0_p2wsh() {
122+
true
123+
} else if features.supports_shutdown_anysegwit() {
124+
script.is_witness_program() && script.as_bytes()[0] != SEGWIT_V0.into_u8()
125+
} else {
126+
false
127+
}
108128
}
109129

110130
impl TryFrom<Script> for ShutdownScript {
@@ -119,10 +139,8 @@ impl TryFrom<(Script, &InitFeatures)> for ShutdownScript {
119139
type Error = InvalidShutdownScript;
120140

121141
fn try_from((script, features): (Script, &InitFeatures)) -> Result<Self, Self::Error> {
122-
if script.is_p2pkh() || script.is_p2sh() || script.is_v0_p2wpkh() || script.is_v0_p2wsh() {
142+
if is_bolt2_compliant(&script, features) {
123143
Ok(Self(ShutdownScriptImpl::Bolt2(script)))
124-
} else if features.supports_shutdown_anysegwit() && script.is_witness_program() && script.as_bytes()[0] != SEGWIT_V0.into_u8() {
125-
Ok(Self(ShutdownScriptImpl::Bolt2(script))) // option_shutdown_anysegwit
126144
} else {
127145
Err(InvalidShutdownScript(script))
128146
}
@@ -147,7 +165,9 @@ mod shutdown_script_tests {
147165
use bitcoin::blockdata::script::{Builder, Script};
148166
use bitcoin::secp256k1::Secp256k1;
149167
use bitcoin::secp256k1::key::{PublicKey, SecretKey};
168+
use ln::features::InitFeatures;
150169
use std::convert::TryFrom;
170+
use core::num::NonZeroU8;
151171

152172
fn pubkey() -> bitcoin::util::ecdsa::PublicKey {
153173
let secp_ctx = Secp256k1::signing_only();
@@ -173,6 +193,8 @@ mod shutdown_script_tests {
173193
let p2wpkh_script = Script::new_v0_wpkh(&pubkey_hash);
174194

175195
let shutdown_script = ShutdownScript::new_p2wpkh_from_pubkey(pubkey.key);
196+
assert!(shutdown_script.is_compatible(&InitFeatures::known()));
197+
assert!(shutdown_script.is_compatible(&InitFeatures::known().clear_shutdown_anysegwit()));
176198
assert_eq!(shutdown_script.into_inner(), p2wpkh_script);
177199
}
178200

@@ -182,6 +204,8 @@ mod shutdown_script_tests {
182204
let p2pkh_script = Script::new_p2pkh(&pubkey_hash);
183205

184206
let shutdown_script = ShutdownScript::new_p2pkh(&pubkey_hash);
207+
assert!(shutdown_script.is_compatible(&InitFeatures::known()));
208+
assert!(shutdown_script.is_compatible(&InitFeatures::known().clear_shutdown_anysegwit()));
185209
assert_eq!(shutdown_script.into_inner(), p2pkh_script);
186210
assert!(ShutdownScript::try_from(p2pkh_script).is_ok());
187211
}
@@ -192,6 +216,8 @@ mod shutdown_script_tests {
192216
let p2sh_script = Script::new_p2sh(&script_hash);
193217

194218
let shutdown_script = ShutdownScript::new_p2sh(&script_hash);
219+
assert!(shutdown_script.is_compatible(&InitFeatures::known()));
220+
assert!(shutdown_script.is_compatible(&InitFeatures::known().clear_shutdown_anysegwit()));
195221
assert_eq!(shutdown_script.into_inner(), p2sh_script);
196222
assert!(ShutdownScript::try_from(p2sh_script).is_ok());
197223
}
@@ -202,6 +228,8 @@ mod shutdown_script_tests {
202228
let p2wpkh_script = Script::new_v0_wpkh(&pubkey_hash);
203229

204230
let shutdown_script = ShutdownScript::new_p2wpkh(&pubkey_hash);
231+
assert!(shutdown_script.is_compatible(&InitFeatures::known()));
232+
assert!(shutdown_script.is_compatible(&InitFeatures::known().clear_shutdown_anysegwit()));
205233
assert_eq!(shutdown_script.into_inner(), p2wpkh_script);
206234
assert!(ShutdownScript::try_from(p2wpkh_script).is_ok());
207235
}
@@ -212,19 +240,39 @@ mod shutdown_script_tests {
212240
let p2wsh_script = Script::new_v0_wsh(&script_hash);
213241

214242
let shutdown_script = ShutdownScript::new_p2wsh(&script_hash);
243+
assert!(shutdown_script.is_compatible(&InitFeatures::known()));
244+
assert!(shutdown_script.is_compatible(&InitFeatures::known().clear_shutdown_anysegwit()));
215245
assert_eq!(shutdown_script.into_inner(), p2wsh_script);
216246
assert!(ShutdownScript::try_from(p2wsh_script).is_ok());
217247
}
218248

249+
#[test]
250+
fn generates_segwit_from_non_v0_witness_program() {
251+
let version = u5::try_from_u8(16).unwrap();
252+
let witness_program = Script::new_witness_program(version, &[0; 40]);
253+
254+
let version = NonZeroU8::new(version.to_u8()).unwrap();
255+
let shutdown_script = ShutdownScript::new_witness_program(version, &[0; 40]);
256+
assert!(shutdown_script.is_compatible(&InitFeatures::known()));
257+
assert!(!shutdown_script.is_compatible(&InitFeatures::known().clear_shutdown_anysegwit()));
258+
assert_eq!(shutdown_script.into_inner(), witness_program);
259+
}
260+
219261
#[test]
220262
fn fails_from_unsupported_script() {
221263
let op_return = Script::new_op_return(&[0; 42]);
222264
assert!(ShutdownScript::try_from(op_return).is_err());
223265
}
224266

225267
#[test]
226-
fn fails_from_invalid_segwit_v0_program() {
268+
fn fails_from_invalid_segwit_v0_witness_program() {
227269
let witness_program = Script::new_witness_program(u5::try_from_u8(0).unwrap(), &[0; 2]);
228270
assert!(ShutdownScript::try_from(witness_program).is_err());
229271
}
272+
273+
#[test]
274+
fn fails_from_invalid_segwit_non_v0_witness_program() {
275+
let witness_program = Script::new_witness_program(u5::try_from_u8(16).unwrap(), &[0; 42]);
276+
assert!(ShutdownScript::try_from(witness_program).is_err());
277+
}
230278
}

0 commit comments

Comments
 (0)