Skip to content

Commit 3cdc711

Browse files
committed
test: ensure multi fragment panic before size limit panic
1 parent da806be commit 3cdc711

File tree

1 file changed

+64
-1
lines changed

1 file changed

+64
-1
lines changed

src/miniscript/mod.rs

+64-1
Original file line numberDiff line numberDiff line change
@@ -829,7 +829,9 @@ mod tests {
829829
use crate::policy::Liftable;
830830
use crate::prelude::*;
831831
use crate::test_utils::{StrKeyTranslator, StrXOnlyKeyTranslator};
832-
use crate::{hex_script, Error, ExtParams, RelLockTime, Satisfier, ToPublicKey};
832+
use crate::{
833+
hex_script, BareCtx, Error, ExtParams, Legacy, RelLockTime, Satisfier, ToPublicKey,
834+
};
833835

834836
type Segwitv0Script = Miniscript<bitcoin::PublicKey, Segwitv0>;
835837
type Tapscript = Miniscript<bitcoin::secp256k1::XOnlyPublicKey, Tap>;
@@ -1634,6 +1636,67 @@ mod tests {
16341636
}
16351637
Tapscript::parse_insane(&script.into_script()).unwrap_err();
16361638
}
1639+
1640+
#[test]
1641+
fn test_context_global_consensus() {
1642+
// Test from string tests
1643+
type LegacyMs = Miniscript<String, Legacy>;
1644+
type Segwitv0Ms = Miniscript<String, Segwitv0>;
1645+
type BareMs = Miniscript<String, BareCtx>;
1646+
1647+
// multisig script of 20 pubkeys exceeds 520 bytes
1648+
let pubkey_vec_20: Vec<String> = (0..20).map(|x| x.to_string()).collect();
1649+
// multisig script of 300 pubkeys exceeds 10,000 bytes
1650+
let pubkey_vec_300: Vec<String> = (0..300).map(|x| x.to_string()).collect();
1651+
1652+
// wrong multi_a for non-tapscript, while exceeding consensus size limit
1653+
let legacy_multi_a_ms =
1654+
LegacyMs::from_str(&format!("multi_a(20,{})", pubkey_vec_20.join(",")));
1655+
let segwit_multi_a_ms =
1656+
Segwitv0Ms::from_str(&format!("multi_a(300,{})", pubkey_vec_300.join(",")));
1657+
let bare_multi_a_ms =
1658+
BareMs::from_str(&format!("multi_a(300,{})", pubkey_vec_300.join(",")));
1659+
1660+
// Should panic for wrong multi_a, even if it exceeds the max consensus size
1661+
assert_eq!(
1662+
legacy_multi_a_ms.unwrap_err().to_string(),
1663+
"Multi a(CHECKSIGADD) only allowed post tapscript"
1664+
);
1665+
assert_eq!(
1666+
segwit_multi_a_ms.unwrap_err().to_string(),
1667+
"Multi a(CHECKSIGADD) only allowed post tapscript"
1668+
);
1669+
assert_eq!(
1670+
bare_multi_a_ms.unwrap_err().to_string(),
1671+
"Multi a(CHECKSIGADD) only allowed post tapscript"
1672+
);
1673+
1674+
// multisig script of 20 pubkeys exceeds 520 bytes
1675+
let multi_ms = format!("multi(20,{})", pubkey_vec_20.join(","));
1676+
// other than legacy, and_v to build 15 nested 20-of-20 multisig script
1677+
// to exceed 10,000 bytes without violation of threshold limit(max: 20)
1678+
let and_v_nested_multi_ms =
1679+
format!("and_v(v:{},", multi_ms).repeat(14) + &multi_ms + "))))))))))))))";
1680+
1681+
// correct multi for non-tapscript, but exceeding consensus size limit
1682+
let legacy_multi_ms = LegacyMs::from_str(&multi_ms);
1683+
let segwit_multi_ms = Segwitv0Ms::from_str(&and_v_nested_multi_ms);
1684+
let bare_multi_ms = BareMs::from_str(&and_v_nested_multi_ms);
1685+
1686+
// Should panic for exceeding the max consensus size, as multi properly used
1687+
assert_eq!(
1688+
legacy_multi_ms.unwrap_err().to_string(),
1689+
"The Miniscript corresponding Script would be larger than MAX_SCRIPT_ELEMENT_SIZE bytes."
1690+
);
1691+
assert_eq!(
1692+
segwit_multi_ms.unwrap_err().to_string(),
1693+
"The Miniscript corresponding Script would be larger than MAX_STANDARD_P2WSH_SCRIPT_SIZE bytes."
1694+
);
1695+
assert_eq!(
1696+
bare_multi_ms.unwrap_err().to_string(),
1697+
"The Miniscript corresponding Script would be larger than MAX_STANDARD_P2WSH_SCRIPT_SIZE bytes."
1698+
);
1699+
}
16371700
}
16381701

16391702
#[cfg(bench)]

0 commit comments

Comments
 (0)