Skip to content

Commit 0451abf

Browse files
committed
Fix broken serde::Deserialize and FromStr impl of keyPair
Fixes #491
1 parent 5e1e012 commit 0451abf

File tree

1 file changed

+46
-6
lines changed

1 file changed

+46
-6
lines changed

src/key.rs

+46-6
Original file line numberDiff line numberDiff line change
@@ -1053,13 +1053,18 @@ impl<'a> From<&'a KeyPair> for PublicKey {
10531053
}
10541054
}
10551055

1056+
#[cfg(feature = "alloc")]
10561057
impl str::FromStr for KeyPair {
10571058
type Err = Error;
10581059

10591060
fn from_str(s: &str) -> Result<Self, Self::Err> {
1060-
let ctx = unsafe {
1061-
Secp256k1::from_raw_all(ffi::secp256k1_context_no_precomp as *mut ffi::Context)
1062-
};
1061+
#[cfg(feature = "global-context")]
1062+
let ctx = SECP256K1;
1063+
1064+
#[cfg(all(not(feature = "global-context"), feature = "alloc"))]
1065+
let ctx = Secp256k1::signing_only();
1066+
1067+
#[allow(clippy::needless_borrow)]
10631068
KeyPair::from_seckey_str(&ctx, s)
10641069
}
10651070
}
@@ -1082,7 +1087,7 @@ impl serde::Serialize for KeyPair {
10821087
}
10831088
}
10841089

1085-
#[cfg(feature = "serde")]
1090+
#[cfg(all(feature = "serde", feature = "alloc"))]
10861091
#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
10871092
impl<'de> serde::Deserialize<'de> for KeyPair {
10881093
fn deserialize<D: serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
@@ -1093,8 +1098,14 @@ impl<'de> serde::Deserialize<'de> for KeyPair {
10931098
} else {
10941099
let visitor = super::serde_util::Tuple32Visitor::new(
10951100
"raw 32 bytes KeyPair",
1096-
|data| unsafe {
1097-
let ctx = Secp256k1::from_raw_all(ffi::secp256k1_context_no_precomp as *mut ffi::Context);
1101+
|data| {
1102+
#[cfg(feature = "global-context")]
1103+
let ctx = SECP256K1;
1104+
1105+
#[cfg(all(not(feature = "global-context"), feature = "alloc"))]
1106+
let ctx = Secp256k1::signing_only();
1107+
1108+
#[allow(clippy::needless_borrow)]
10981109
KeyPair::from_seckey_slice(&ctx, data)
10991110
}
11001111
);
@@ -1630,12 +1641,14 @@ pub mod serde_keypair {
16301641
#[cfg(test)]
16311642
#[allow(unused_imports)]
16321643
mod test {
1644+
use bitcoin_hashes::hex::ToHex;
16331645
use super::*;
16341646

16351647
use core::str::FromStr;
16361648

16371649
#[cfg(any(feature = "alloc", feature = "std"))]
16381650
use rand::{Error, RngCore, thread_rng, rngs::mock::StepRng};
1651+
use serde_test::{Configure, Token};
16391652

16401653
#[cfg(target_arch = "wasm32")]
16411654
use wasm_bindgen_test::wasm_bindgen_test as test;
@@ -2431,6 +2444,33 @@ mod test {
24312444
assert_tokens(&pk.readable(), &[Token::Str(PK_STR)]);
24322445
assert_tokens(&pk.readable(), &[Token::String(PK_STR)]);
24332446
}
2447+
2448+
#[test]
2449+
#[cfg(feature = "alloc")]
2450+
fn test_keypair_from_str() {
2451+
let ctx = crate::Secp256k1::new();
2452+
let keypair = KeyPair::new(&ctx, &mut thread_rng());
2453+
let msg = keypair.secret_key().secret_bytes().to_hex();
2454+
let parsed_key: KeyPair = msg.parse().unwrap();
2455+
assert_eq!(parsed_key, keypair);
2456+
}
2457+
2458+
#[test]
2459+
#[cfg(all(feature= "alloc", feature = "serde"))]
2460+
fn test_keypair_deserialize_serde() {
2461+
let ctx = crate::Secp256k1::new();
2462+
let sec_key_str = "4242424242424242424242424242424242424242424242424242424242424242";
2463+
let keypair = KeyPair::from_seckey_str(&ctx, sec_key_str).unwrap();
2464+
2465+
serde_test::assert_tokens(&keypair.readable(), &[Token::String(&sec_key_str)]);
2466+
2467+
let sec_key_bytes = keypair.secret_key().secret_bytes();
2468+
let tokens = std::iter::once(Token::Tuple { len: 32 })
2469+
.chain(sec_key_bytes.iter().copied().map(Token::U8))
2470+
.chain(std::iter::once(Token::TupleEnd))
2471+
.collect::<Vec<_>>();
2472+
serde_test::assert_tokens(&keypair.compact(), &tokens);
2473+
}
24342474
}
24352475

24362476
#[cfg(bench)]

0 commit comments

Comments
 (0)