From e250426963e31411d6264ee29fce509624c55893 Mon Sep 17 00:00:00 2001 From: yihuang Date: Mon, 13 Jul 2020 12:13:47 +0800 Subject: [PATCH] make dependency secp256k1 optional, fix #391 --- light-client/Cargo.toml | 3 +++ rpc/Cargo.toml | 1 + tendermint/Cargo.toml | 7 +++++-- tendermint/src/account.rs | 7 ++++++- tendermint/src/amino_types/ed25519.rs | 1 + tendermint/src/config/node_key.rs | 1 + tendermint/src/public_key.rs | 25 ++++++++++++++++++------- tendermint/src/validator.rs | 1 + 8 files changed, 36 insertions(+), 10 deletions(-) diff --git a/light-client/Cargo.toml b/light-client/Cargo.toml index 0d0c94e0c..7b1b75531 100644 --- a/light-client/Cargo.toml +++ b/light-client/Cargo.toml @@ -26,3 +26,6 @@ tokio = "0.2.20" [dev-dependencies] serde_json = "1.0.51" gumdrop = "0.8.0" + +[features] +secp256k1 = ["tendermint/secp256k1", "tendermint-rpc/secp256k1"] diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml index c70d6446e..0ce22b669 100644 --- a/rpc/Cargo.toml +++ b/rpc/Cargo.toml @@ -20,6 +20,7 @@ all-features = true [features] default = [] client = [ "async-tungstenite", "futures", "http", "hyper", "tokio" ] +secp256k1 = ["tendermint/secp256k1"] [dependencies] bytes = "0.5" diff --git a/tendermint/Cargo.toml b/tendermint/Cargo.toml index 54bda823d..1e9ef0599 100644 --- a/tendermint/Cargo.toml +++ b/tendermint/Cargo.toml @@ -47,15 +47,18 @@ serde_repr = "0.1" sha2 = { version = "0.9", default-features = false } signatory = { version = "0.20", features = ["ed25519", "ecdsa"] } signatory-dalek = "0.20" -signatory-secp256k1 = "0.20" +signatory-secp256k1 = { version = "0.20", optional = true } subtle = "2" subtle-encoding = { version = "0.5", features = ["bech32-preview"] } tai64 = { version = "3", features = ["chrono"] } thiserror = "1" toml = { version = "0.5" } zeroize = { version = "1.1", features = ["zeroize_derive"] } -ripemd160 = "0.9" +ripemd160 = { version = "0.9", optional = true } [dev-dependencies] tendermint-rpc = { path = "../rpc", features = [ "client" ] } tokio = { version = "0.2", features = [ "macros" ] } + +[features] +secp256k1 = ["signatory-secp256k1", "ripemd160"] diff --git a/tendermint/src/account.rs b/tendermint/src/account.rs index c16f2242a..623d9472a 100644 --- a/tendermint/src/account.rs +++ b/tendermint/src/account.rs @@ -1,10 +1,13 @@ //! Tendermint accounts use crate::error::{Error, Kind}; +#[cfg(feature = "secp256k1")] use ripemd160::Ripemd160; use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; use sha2::{Digest, Sha256}; -use signatory::{ecdsa::curve::secp256k1, ed25519}; +#[cfg(feature = "secp256k1")] +use signatory::ecdsa::curve::secp256k1; +use signatory::ed25519; use std::{ fmt::{self, Debug, Display}, str::FromStr, @@ -60,6 +63,7 @@ impl Debug for Id { } // RIPEMD160(SHA256(pk)) +#[cfg(feature = "secp256k1")] impl From for Id { fn from(pk: secp256k1::PublicKey) -> Id { let sha_digest = Sha256::digest(pk.as_bytes()); @@ -144,6 +148,7 @@ mod tests { } #[test] + #[cfg(feature = "secp256k1")] fn test_secp_id() { // test vector for pubkey and id (address) let pubkey_hex = "02950E1CDFCB133D6024109FD489F734EEB4502418E538C28481F22BCE276F248C"; diff --git a/tendermint/src/amino_types/ed25519.rs b/tendermint/src/amino_types/ed25519.rs index 8c50103e2..d63cb8767 100644 --- a/tendermint/src/amino_types/ed25519.rs +++ b/tendermint/src/amino_types/ed25519.rs @@ -40,6 +40,7 @@ impl From for PubKeyResponse { PublicKey::Ed25519(ref pk) => PubKeyResponse { pub_key_ed25519: pk.as_bytes().to_vec(), }, + #[cfg(feature = "secp256k1")] PublicKey::Secp256k1(_) => panic!("secp256k1 PubKeyResponse unimplemented"), } } diff --git a/tendermint/src/config/node_key.rs b/tendermint/src/config/node_key.rs index d817d0cd1..44a7178a1 100644 --- a/tendermint/src/config/node_key.rs +++ b/tendermint/src/config/node_key.rs @@ -48,6 +48,7 @@ impl NodeKey { /// Get node ID for this keypair pub fn node_id(&self) -> node::Id { + #[allow(unreachable_patterns)] match &self.public_key() { PublicKey::Ed25519(key) => node::Id::from(*key), _ => unreachable!(), diff --git a/tendermint/src/public_key.rs b/tendermint/src/public_key.rs index f47fdbefd..0b2e3d38b 100644 --- a/tendermint/src/public_key.rs +++ b/tendermint/src/public_key.rs @@ -3,7 +3,9 @@ use crate::error::{Error, Kind}; use anomaly::fail; use serde::{de::Error as _, Deserialize, Deserializer, Serialize, Serializer}; -use signatory::{ecdsa::curve::secp256k1, ed25519}; +#[cfg(feature = "signatory-secp256k1")] +use signatory::ecdsa::curve::secp256k1; +use signatory::ed25519; use std::{ fmt::{self, Display}, ops::Deref, @@ -26,6 +28,7 @@ pub enum PublicKey { Ed25519(ed25519::PublicKey), /// Secp256k1 keys + #[cfg(feature = "signatory-secp256k1")] #[serde( rename = "tendermint/PubKeySecp256k1", serialize_with = "serialize_secp256k1_base64", @@ -36,6 +39,7 @@ pub enum PublicKey { impl PublicKey { /// From raw secp256k1 public key bytes + #[cfg(feature = "signatory-secp256k1")] pub fn from_raw_secp256k1(bytes: &[u8]) -> Option { Some(PublicKey::Secp256k1(secp256k1::PublicKey::from_bytes( bytes, @@ -49,6 +53,7 @@ impl PublicKey { /// Get Ed25519 public key pub fn ed25519(self) -> Option { + #[allow(unreachable_patterns)] match self { PublicKey::Ed25519(pk) => Some(pk), _ => None, @@ -59,6 +64,7 @@ impl PublicKey { pub fn as_bytes(self) -> Vec { match self { PublicKey::Ed25519(ref pk) => pk.as_bytes(), + #[cfg(feature = "signatory-secp256k1")] PublicKey::Secp256k1(ref pk) => pk.as_bytes(), } .to_vec() @@ -73,6 +79,7 @@ impl PublicKey { key_bytes.extend(pk.as_bytes()); key_bytes } + #[cfg(feature = "signatory-secp256k1")] PublicKey::Secp256k1(ref pk) => { let mut key_bytes = vec![0xEB, 0x5A, 0xE9, 0x87, 0x21]; key_bytes.extend(pk.as_bytes()); @@ -98,6 +105,7 @@ impl From for PublicKey { } } +#[cfg(feature = "signatory-secp256k1")] impl From for PublicKey { fn from(pk: secp256k1::PublicKey) -> PublicKey { PublicKey::Secp256k1(pk) @@ -118,14 +126,15 @@ impl TendermintKey { /// Create a new account key from a `PublicKey` pub fn new_account_key(public_key: PublicKey) -> Result { match public_key { - PublicKey::Ed25519(_) | PublicKey::Secp256k1(_) => { - Ok(TendermintKey::AccountKey(public_key)) - } + PublicKey::Ed25519(_) => Ok(TendermintKey::AccountKey(public_key)), + #[cfg(feature = "signatory-secp256k1")] + PublicKey::Secp256k1(_) => Ok(TendermintKey::AccountKey(public_key)), } } /// Create a new consensus key from a `PublicKey` pub fn new_consensus_key(public_key: PublicKey) -> Result { + #[allow(unreachable_patterns)] match public_key { PublicKey::Ed25519(_) => Ok(TendermintKey::AccountKey(public_key)), _ => fail!( @@ -209,6 +218,7 @@ where } /// Serialize the bytes of a secp256k1 ECDSA public key as Base64. Used for serializing JSON +#[cfg(feature = "secp256k1")] fn serialize_secp256k1_base64( pk: &secp256k1::PublicKey, serializer: S, @@ -231,6 +241,7 @@ where ed25519::PublicKey::from_bytes(&bytes).ok_or_else(|| D::Error::custom("invalid ed25519 key")) } +#[cfg(feature = "secp256k1")] fn deserialize_secp256k1_base64<'de, D>( deserializer: D, ) -> Result @@ -265,11 +276,11 @@ mod tests { ); } - const EXAMPLE_ACCOUNT_KEY: &str = - "02A1633CAFCC01EBFB6D78E39F687A1F0995C62FC95F51EAD10A02EE0BE551B5DC"; - #[test] + #[cfg(feature = "secp256k1")] fn test_account_serialization() { + const EXAMPLE_ACCOUNT_KEY: &str = + "02A1633CAFCC01EBFB6D78E39F687A1F0995C62FC95F51EAD10A02EE0BE551B5DC"; let example_key = TendermintKey::AccountKey( PublicKey::from_raw_secp256k1(&hex::decode_upper(EXAMPLE_ACCOUNT_KEY).unwrap()) .unwrap(), diff --git a/tendermint/src/validator.rs b/tendermint/src/validator.rs index 7d131aba3..d34a37798 100644 --- a/tendermint/src/validator.rs +++ b/tendermint/src/validator.rs @@ -101,6 +101,7 @@ impl From for account::Id { fn from(pub_key: PublicKey) -> account::Id { match pub_key { PublicKey::Ed25519(pk) => account::Id::from(pk), + #[cfg(feature = "signatory-secp256k1")] PublicKey::Secp256k1(pk) => account::Id::from(pk), } }