diff --git a/src/miniscript/mod.rs b/src/miniscript/mod.rs index f5ca05fdb..cee628d5d 100644 --- a/src/miniscript/mod.rs +++ b/src/miniscript/mod.rs @@ -1634,6 +1634,67 @@ mod tests { } Tapscript::parse_insane(&script.into_script()).unwrap_err(); } + + #[test] + fn test_context_global_consensus() { + // Test from string tests + type LegacyMs = Miniscript; + type Segwitv0Ms = Miniscript; + type BareMs = Miniscript; + + // multisig script of 20 pubkeys exceeds 520 bytes + let pubkey_vec_20: Vec = (0..20).map(|x| x.to_string()).collect(); + // multisig script of 300 pubkeys exceeds 10,000 bytes + let pubkey_vec_300: Vec = (0..300).map(|x| x.to_string()).collect(); + + // wrong multi_a for non-tapscript, while exceeding consensus size limit + let legacy_multi_a_ms = + LegacyMs::from_str(&format!("multi_a(20,{})", pubkey_vec_20.join(","))); + let segwit_multi_a_ms = + Segwitv0Ms::from_str(&format!("multi_a(300,{})", pubkey_vec_300.join(","))); + let bare_multi_a_ms = + BareMs::from_str(&format!("multi_a(300,{})", pubkey_vec_300.join(","))); + + // Should panic for wrong multi_a, even if it exceeds the max consensus size + assert_eq!( + legacy_multi_a_ms.unwrap_err().to_string(), + "Multi a(CHECKSIGADD) only allowed post tapscript" + ); + assert_eq!( + segwit_multi_a_ms.unwrap_err().to_string(), + "Multi a(CHECKSIGADD) only allowed post tapscript" + ); + assert_eq!( + bare_multi_a_ms.unwrap_err().to_string(), + "Multi a(CHECKSIGADD) only allowed post tapscript" + ); + + // multisig script of 20 pubkeys exceeds 520 bytes + let multi_ms = format!("multi(20,{})", pubkey_vec_20.join(",")); + // other than legacy, and_v to build 15 nested 20-of-20 multisig script + // to exceed 10,000 bytes without violation of threshold limit(max: 20) + let and_v_nested_multi_ms = + format!("and_v(v:{},", multi_ms).repeat(14) + &multi_ms + "))))))))))))))"; + + // correct multi for non-tapscript, but exceeding consensus size limit + let legacy_multi_ms = LegacyMs::from_str(&multi_ms); + let segwit_multi_ms = Segwitv0Ms::from_str(&and_v_nested_multi_ms); + let bare_multi_ms = BareMs::from_str(&and_v_nested_multi_ms); + + // Should panic for exceeding the max consensus size, as multi properly used + assert_eq!( + legacy_multi_ms.unwrap_err().to_string(), + "The Miniscript corresponding Script would be larger than MAX_SCRIPT_ELEMENT_SIZE bytes." + ); + assert_eq!( + segwit_multi_ms.unwrap_err().to_string(), + "The Miniscript corresponding Script would be larger than MAX_STANDARD_P2WSH_SCRIPT_SIZE bytes." + ); + assert_eq!( + bare_multi_ms.unwrap_err().to_string(), + "The Miniscript corresponding Script would be larger than MAX_STANDARD_P2WSH_SCRIPT_SIZE bytes." + ); + } } #[cfg(bench)]