Skip to content

Commit

Permalink
Remove prost from core
Browse files Browse the repository at this point in the history
  • Loading branch information
kckeiks committed Oct 26, 2022
1 parent 437b387 commit 24d5a60
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 109 deletions.
4 changes: 2 additions & 2 deletions core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ multistream-select = { version = "0.12", path = "../misc/multistream-select" }
p256 = { version = "0.11.1", default-features = false, features = ["ecdsa"], optional = true }
parking_lot = "0.12.0"
pin-project = "1.0.0"
prost = "0.11"
quick-protobuf = "0.8"
rand = "0.8"
rw-stream-sink = { version = "0.3.0", path = "../misc/rw-stream-sink" }
sha2 = "0.10.0"
Expand All @@ -53,7 +53,7 @@ rmp-serde = "1.0"
serde_json = "1.0"

[build-dependencies]
prost-build = "0.11"
pb-rs = "0.9.1"

[features]
secp256k1 = [ "libsecp256k1" ]
Expand Down
36 changes: 27 additions & 9 deletions core/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,32 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

use pb_rs::{types::FileDescriptor, ConfigBuilder};
use std::path::{Path, PathBuf};

fn main() {
prost_build::compile_protos(
&[
"src/keys.proto",
"src/envelope.proto",
"src/peer_record.proto",
],
&["src"],
)
.unwrap();
let out_dir = std::env::var("OUT_DIR").unwrap();
let out_dir = Path::new(&out_dir).join("protos");

let in_dir = PathBuf::from(::std::env::var("CARGO_MANIFEST_DIR").unwrap()).join("src");

// Find all *.proto files in the `in_dir` and add them to the list of files
let mut protos = Vec::new();
let proto_ext = Some(Path::new("proto").as_os_str());

for entry in std::fs::read_dir(&in_dir).unwrap() {
let path = entry.unwrap().path();
if path.extension() == proto_ext {
protos.push(path);
}
}

// Delete all old generated files before re-generating new ones
if out_dir.exists() {
std::fs::remove_dir_all(&out_dir).unwrap();
}

std::fs::DirBuilder::new().create(&out_dir).unwrap();
let config_builder = ConfigBuilder::new(&protos, None, Some(&out_dir), &[in_dir]).unwrap();
FileDescriptor::run(&config_builder.build()).unwrap()
}
85 changes: 34 additions & 51 deletions core/src/identity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ pub mod error;

use self::error::*;
use crate::{keys_proto, PeerId};
use std::borrow::Cow;
use std::convert::{TryFrom, TryInto};

/// Identity keypair of a node.
Expand Down Expand Up @@ -147,12 +148,10 @@ impl Keypair {

/// Encode a private key as protobuf structure.
pub fn to_protobuf_encoding(&self) -> Result<Vec<u8>, DecodingError> {
use prost::Message;

let pk = match self {
Self::Ed25519(data) => keys_proto::PrivateKey {
r#type: keys_proto::KeyType::Ed25519.into(),
data: data.encode().into(),
Type: keys_proto::KeyType::Ed25519,
Data: Cow::from(data.encode().to_vec()),
},
#[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
Self::Rsa(_) => {
Expand All @@ -174,42 +173,37 @@ impl Keypair {
}
};

Ok(pk.encode_to_vec())
Ok(quick_protobuf::serialize_into_vec(&pk).expect("Encoding to succeed."))
}

/// Decode a private key from a protobuf structure and parse it as a [`Keypair`].
pub fn from_protobuf_encoding(bytes: &[u8]) -> Result<Keypair, DecodingError> {
use prost::Message;

let mut private_key = keys_proto::PrivateKey::decode(bytes)
.map_err(|e| DecodingError::new("Protobuf").source(e))
.map(zeroize::Zeroizing::new)?;
let mut private_key: zeroize::Zeroizing<keys_proto::PrivateKey> =
quick_protobuf::deserialize_from_slice(bytes)
.map_err(|e| DecodingError::new("Protobuf").source(e))
.map(zeroize::Zeroizing::new)?;

let key_type = keys_proto::KeyType::from_i32(private_key.r#type).ok_or_else(|| {
DecodingError::new(format!("unknown key type: {}", private_key.r#type))
})?;

match key_type {
match private_key.Type {
keys_proto::KeyType::Ed25519 => {
ed25519::Keypair::decode(&mut private_key.data).map(Keypair::Ed25519)
ed25519::Keypair::decode(private_key.Data.to_mut()).map(Keypair::Ed25519)
}
keys_proto::KeyType::Rsa => Err(DecodingError::new(
keys_proto::KeyType::RSA => Err(DecodingError::new(
"Decoding RSA key from Protobuf is unsupported.",
)),
keys_proto::KeyType::Secp256k1 => Err(DecodingError::new(
"Decoding Secp256k1 key from Protobuf is unsupported.",
)),
keys_proto::KeyType::Ecdsa => Err(DecodingError::new(
keys_proto::KeyType::ECDSA => Err(DecodingError::new(
"Decoding ECDSA key from Protobuf is unsupported.",
)),
}
}
}

impl zeroize::Zeroize for keys_proto::PrivateKey {
impl zeroize::Zeroize for keys_proto::PrivateKey<'_> {
fn zeroize(&mut self) {
self.r#type.zeroize();
self.data.zeroize();
self.Type = keys_proto::KeyType::RSA;
self.Data.to_mut().zeroize();
}
}

Expand Down Expand Up @@ -251,23 +245,15 @@ impl PublicKey {
/// Encode the public key into a protobuf structure for storage or
/// exchange with other nodes.
pub fn to_protobuf_encoding(&self) -> Vec<u8> {
use prost::Message;

let public_key = keys_proto::PublicKey::from(self);

let mut buf = Vec::with_capacity(public_key.encoded_len());
public_key
.encode(&mut buf)
.expect("Vec<u8> provides capacity as needed");
buf
quick_protobuf::serialize_into_vec(&public_key).expect("Encoding to succeed.")
}

/// Decode a public key from a protobuf structure, e.g. read from storage
/// or received from another node.
pub fn from_protobuf_encoding(bytes: &[u8]) -> Result<PublicKey, DecodingError> {
use prost::Message;

let pubkey = keys_proto::PublicKey::decode(bytes)
let pubkey: keys_proto::PublicKey = quick_protobuf::deserialize_from_slice(bytes)
.map_err(|e| DecodingError::new("Protobuf").source(e))?;

pubkey.try_into()
Expand All @@ -279,55 +265,52 @@ impl PublicKey {
}
}

impl From<&PublicKey> for keys_proto::PublicKey {
impl From<&PublicKey> for keys_proto::PublicKey<'_> {
fn from(key: &PublicKey) -> Self {
match key {
PublicKey::Ed25519(key) => keys_proto::PublicKey {
r#type: keys_proto::KeyType::Ed25519 as i32,
data: key.encode().to_vec(),
Type: keys_proto::KeyType::Ed25519,
Data: Cow::from(key.encode().to_vec()),
},
#[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
PublicKey::Rsa(key) => keys_proto::PublicKey {
r#type: keys_proto::KeyType::Rsa as i32,
data: key.encode_x509(),
Type: keys_proto::KeyType::RSA,
Data: Cow::from(key.encode_x509()),
},
#[cfg(feature = "secp256k1")]
PublicKey::Secp256k1(key) => keys_proto::PublicKey {
r#type: keys_proto::KeyType::Secp256k1 as i32,
data: key.encode().to_vec(),
Type: keys_proto::KeyType::Secp256k1,
Data: Cow::from(key.encode().to_vec()),
},
#[cfg(feature = "ecdsa")]
PublicKey::Ecdsa(key) => keys_proto::PublicKey {
r#type: keys_proto::KeyType::Ecdsa as i32,
data: key.encode_der(),
Type: keys_proto::KeyType::ECDSA,
Data: Cow::from(key.encode_der()),
},
}
}
}

impl TryFrom<keys_proto::PublicKey> for PublicKey {
impl TryFrom<keys_proto::PublicKey<'_>> for PublicKey {
type Error = DecodingError;

fn try_from(pubkey: keys_proto::PublicKey) -> Result<Self, Self::Error> {
let key_type = keys_proto::KeyType::from_i32(pubkey.r#type)
.ok_or_else(|| DecodingError::new(format!("unknown key type: {}", pubkey.r#type)))?;

match key_type {
match pubkey.Type {
keys_proto::KeyType::Ed25519 => {
ed25519::PublicKey::decode(&pubkey.data).map(PublicKey::Ed25519)
ed25519::PublicKey::decode(&pubkey.Data).map(PublicKey::Ed25519)
}
#[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
keys_proto::KeyType::Rsa => {
rsa::PublicKey::decode_x509(&pubkey.data).map(PublicKey::Rsa)
rsa::PublicKey::decode_x509(&pubkey.Data).map(PublicKey::Rsa)
}
#[cfg(any(not(feature = "rsa"), target_arch = "wasm32"))]
keys_proto::KeyType::Rsa => {
keys_proto::KeyType::RSA => {
log::debug!("support for RSA was disabled at compile-time");
Err(DecodingError::new("Unsupported"))
}
#[cfg(feature = "secp256k1")]
keys_proto::KeyType::Secp256k1 => {
secp256k1::PublicKey::decode(&pubkey.data).map(PublicKey::Secp256k1)
secp256k1::PublicKey::decode(&pubkey.Data).map(PublicKey::Secp256k1)
}
#[cfg(not(feature = "secp256k1"))]
keys_proto::KeyType::Secp256k1 => {
Expand All @@ -336,10 +319,10 @@ impl TryFrom<keys_proto::PublicKey> for PublicKey {
}
#[cfg(feature = "ecdsa")]
keys_proto::KeyType::Ecdsa => {
ecdsa::PublicKey::decode_der(&pubkey.data).map(PublicKey::Ecdsa)
ecdsa::PublicKey::decode_der(&pubkey.Data).map(PublicKey::Ecdsa)
}
#[cfg(not(feature = "ecdsa"))]
keys_proto::KeyType::Ecdsa => {
keys_proto::KeyType::ECDSA => {
log::debug!("support for ECDSA was disabled at compile-time");
Err(DecodingError::new("Unsupported"))
}
Expand Down
13 changes: 3 additions & 10 deletions core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,11 @@
#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]

#[allow(clippy::derive_partial_eq_without_eq)]
mod keys_proto {
include!(concat!(env!("OUT_DIR"), "/keys_proto.rs"));
mod protos {
include!(concat!(env!("OUT_DIR"), "/protos/mod.rs"));
}

mod envelope_proto {
include!(concat!(env!("OUT_DIR"), "/envelope_proto.rs"));
}

#[allow(clippy::derive_partial_eq_without_eq)]
mod peer_record_proto {
include!(concat!(env!("OUT_DIR"), "/peer_record_proto.rs"));
}
use protos::*;

/// Multi-address re-export.
pub use multiaddr;
Expand Down
28 changes: 11 additions & 17 deletions core/src/peer_record.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use crate::identity::Keypair;
use crate::signed_envelope::SignedEnvelope;
use crate::{peer_record_proto, signed_envelope, Multiaddr, PeerId};
use instant::SystemTime;
use std::borrow::Cow;
use std::convert::TryInto;
use std::fmt;

Expand Down Expand Up @@ -30,11 +31,10 @@ impl PeerRecord {
///
/// If this function succeeds, the [`SignedEnvelope`] contained a peer record with a valid signature and can hence be considered authenticated.
pub fn from_signed_envelope(envelope: SignedEnvelope) -> Result<Self, FromEnvelopeError> {
use prost::Message;

let (payload, signing_key) =
envelope.payload_and_signing_key(String::from(DOMAIN_SEP), PAYLOAD_TYPE.as_bytes())?;
let record = peer_record_proto::PeerRecord::decode(payload)?;
let record: peer_record_proto::PeerRecord =
quick_protobuf::deserialize_from_slice(payload)?;

let peer_id = PeerId::from_bytes(&record.peer_id)?;

Expand All @@ -46,7 +46,7 @@ impl PeerRecord {
let addresses = record
.addresses
.into_iter()
.map(|a| a.multiaddr.try_into())
.map(|a| a.multiaddr.to_vec().try_into())
.collect::<Result<Vec<_>, _>>()?;

Ok(Self {
Expand All @@ -61,8 +61,6 @@ impl PeerRecord {
///
/// This is the same key that is used for authenticating every libp2p connection of your application, i.e. what you use when setting up your [`crate::transport::Transport`].
pub fn new(key: &Keypair, addresses: Vec<Multiaddr>) -> Result<Self, SigningError> {
use prost::Message;

let seq = SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.expect("now() is never before UNIX_EPOCH")
Expand All @@ -71,21 +69,17 @@ impl PeerRecord {

let payload = {
let record = peer_record_proto::PeerRecord {
peer_id: peer_id.to_bytes(),
peer_id: Cow::from(peer_id.to_bytes()),
seq,
addresses: addresses
.iter()
.map(|m| peer_record_proto::peer_record::AddressInfo {
multiaddr: m.to_vec(),
.map(|m| peer_record_proto::mod_PeerRecord::AddressInfo {
multiaddr: Cow::from(m.to_vec()),
})
.collect(),
};

let mut buf = Vec::with_capacity(record.encoded_len());
record
.encode(&mut buf)
.expect("Vec<u8> provides capacity as needed");
buf
quick_protobuf::serialize_into_vec(&record).expect("Encoding to succeed.")
};

let envelope = SignedEnvelope::new(
Expand Down Expand Up @@ -129,7 +123,7 @@ pub enum FromEnvelopeError {
/// Failed to extract the payload from the envelope.
BadPayload(signed_envelope::ReadPayloadError),
/// Failed to decode the provided bytes as a [`PeerRecord`].
InvalidPeerRecord(prost::DecodeError),
InvalidPeerRecord(quick_protobuf::Error),
/// Failed to decode the peer ID.
InvalidPeerId(multihash::Error),
/// The signer of the envelope is different than the peer id in the record.
Expand All @@ -144,8 +138,8 @@ impl From<signed_envelope::ReadPayloadError> for FromEnvelopeError {
}
}

impl From<prost::DecodeError> for FromEnvelopeError {
fn from(e: prost::DecodeError) -> Self {
impl From<quick_protobuf::Error> for FromEnvelopeError {
fn from(e: quick_protobuf::Error) -> Self {
Self::InvalidPeerRecord(e)
}
}
Expand Down
Loading

0 comments on commit 24d5a60

Please sign in to comment.