Skip to content

Commit b35b5d9

Browse files
committed
fix: properly detect testnet keys in wildcard descriptors
- Add detection for testnet extended key prefixes (tpub, tprv, upub, uprv, vpub, vprv) - Set ok_for_mainnet=false for descriptors using testnet keys - Log at info level whether descriptor uses mainnet or testnet keys - Add tests for testnet key detection and ok_for_mainnet validation
1 parent d5446a8 commit b35b5d9

File tree

1 file changed

+63
-2
lines changed
  • stratum-apps/src/config_helpers/coinbase_output

1 file changed

+63
-2
lines changed

stratum-apps/src/config_helpers/coinbase_output/mod.rs

Lines changed: 63 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,25 @@ use miniscript::{
66
descriptor::DescriptorPublicKey,
77
DefiniteDescriptorKey, Descriptor,
88
};
9+
use tracing::info;
910

1011
pub use errors::Error;
1112

13+
/// Testnet extended key prefixes (BIP32/BIP49/BIP84).
14+
/// These indicate the key is for testnet/regtest, not mainnet.
15+
const TESTNET_KEY_PREFIXES: &[&str] = &[
16+
"tpub", "tprv", // BIP32 testnet
17+
"upub", "uprv", // BIP49 testnet (P2WPKH-P2SH)
18+
"vpub", "vprv", // BIP84 testnet (P2WPKH native)
19+
];
20+
21+
/// Returns true if the descriptor string contains any testnet extended key prefixes.
22+
fn descriptor_uses_testnet_keys(descriptor: &str) -> bool {
23+
TESTNET_KEY_PREFIXES
24+
.iter()
25+
.any(|prefix| descriptor.contains(prefix))
26+
}
27+
1228
/// Coinbase output transaction.
1329
///
1430
/// Typically used for parsing coinbase outputs defined in SRI role configuration files.
@@ -52,9 +68,23 @@ impl CoinbaseRewardScript {
5268
.at_derivation_index(0)
5369
.map_err(|e| Error::Miniscript(miniscript::Error::Unexpected(e.to_string())))?;
5470

71+
// Detect if this is a testnet key based on the key prefix
72+
let uses_testnet_keys = descriptor_uses_testnet_keys(s);
73+
let ok_for_mainnet = !uses_testnet_keys;
74+
75+
if uses_testnet_keys {
76+
info!(
77+
"Coinbase descriptor uses testnet keys (tpub/upub/vpub) - not valid for mainnet"
78+
);
79+
} else {
80+
info!(
81+
"Coinbase descriptor uses mainnet keys (xpub/ypub/zpub) - valid for mainnet"
82+
);
83+
}
84+
5585
return Ok(Self {
5686
script_pubkey: definite.script_pubkey(),
57-
ok_for_mainnet: true,
87+
ok_for_mainnet,
5888
wildcard_descriptor_str: Some(s.to_string()),
5989
});
6090
}
@@ -482,7 +512,38 @@ mod tests {
482512
).unwrap();
483513

484514
assert!(desc.has_wildcard());
485-
// Mainnet xpubs are allowed
515+
// Mainnet xpubs are valid for mainnet
486516
assert!(desc.ok_for_mainnet());
487517
}
518+
519+
#[test]
520+
fn test_testnet_tpub_wildcard_not_ok_for_mainnet() {
521+
// Testnet tpub with wildcard - should NOT be ok for mainnet
522+
let desc = CoinbaseRewardScript::from_descriptor(
523+
"wpkh(tpubD6NzVbkrYhZ4XgiXtGrdW5XDAPFCL9h7we1vwNCpn8tGbBcgfVYjXyhWo4E1xkh56hjod1RhGjxbaTLV3X4FyWuejifB9jusQ46QzG87VKp/0/*)"
524+
).unwrap();
525+
526+
assert!(desc.has_wildcard());
527+
// Testnet tpubs are NOT valid for mainnet
528+
assert!(!desc.ok_for_mainnet());
529+
}
530+
531+
#[test]
532+
fn test_testnet_key_detection() {
533+
// Test the testnet key detection helper
534+
assert!(super::descriptor_uses_testnet_keys("wpkh(tpub.../0/*)"));
535+
assert!(super::descriptor_uses_testnet_keys("wpkh(tprv.../0/*)"));
536+
assert!(super::descriptor_uses_testnet_keys("wpkh(upub.../0/*)"));
537+
assert!(super::descriptor_uses_testnet_keys("wpkh(uprv.../0/*)"));
538+
assert!(super::descriptor_uses_testnet_keys("wpkh(vpub.../0/*)"));
539+
assert!(super::descriptor_uses_testnet_keys("wpkh(vprv.../0/*)"));
540+
541+
// Mainnet keys should return false
542+
assert!(!super::descriptor_uses_testnet_keys("wpkh(xpub.../0/*)"));
543+
assert!(!super::descriptor_uses_testnet_keys("wpkh(xprv.../0/*)"));
544+
assert!(!super::descriptor_uses_testnet_keys("wpkh(ypub.../0/*)"));
545+
assert!(!super::descriptor_uses_testnet_keys("wpkh(yprv.../0/*)"));
546+
assert!(!super::descriptor_uses_testnet_keys("wpkh(zpub.../0/*)"));
547+
assert!(!super::descriptor_uses_testnet_keys("wpkh(zprv.../0/*)"));
548+
}
488549
}

0 commit comments

Comments
 (0)