mirror of
https://github.com/fluencelabs/rust-libp2p
synced 2025-06-24 07:11:38 +00:00
feat: migrate to quick-protobuf
Instead of relying on `protoc` and buildscripts, we generate the bindings using `pb-rs` and version them within our codebase. This makes for a better IDE integration, a faster build and an easier use of `rust-libp2p` because we don't force the `protoc` dependency onto them. Resolves #3024. Pull-Request: #3312.
This commit is contained in:
59
core/src/generated/envelope_proto.rs
Normal file
59
core/src/generated/envelope_proto.rs
Normal file
@ -0,0 +1,59 @@
|
||||
// Automatically generated rust module for 'envelope.proto' file
|
||||
|
||||
#![allow(non_snake_case)]
|
||||
#![allow(non_upper_case_globals)]
|
||||
#![allow(non_camel_case_types)]
|
||||
#![allow(unused_imports)]
|
||||
#![allow(unknown_lints)]
|
||||
#![allow(clippy::all)]
|
||||
#![cfg_attr(rustfmt, rustfmt_skip)]
|
||||
|
||||
|
||||
use quick_protobuf::{MessageInfo, MessageRead, MessageWrite, BytesReader, Writer, WriterBackend, Result};
|
||||
use quick_protobuf::sizeofs::*;
|
||||
use super::*;
|
||||
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Debug, Default, PartialEq, Clone)]
|
||||
pub struct Envelope {
|
||||
pub public_key: Option<keys_proto::PublicKey>,
|
||||
pub payload_type: Vec<u8>,
|
||||
pub payload: Vec<u8>,
|
||||
pub signature: Vec<u8>,
|
||||
}
|
||||
|
||||
impl<'a> MessageRead<'a> for Envelope {
|
||||
fn from_reader(r: &mut BytesReader, bytes: &'a [u8]) -> Result<Self> {
|
||||
let mut msg = Self::default();
|
||||
while !r.is_eof() {
|
||||
match r.next_tag(bytes) {
|
||||
Ok(10) => msg.public_key = Some(r.read_message::<keys_proto::PublicKey>(bytes)?),
|
||||
Ok(18) => msg.payload_type = r.read_bytes(bytes)?.to_owned(),
|
||||
Ok(26) => msg.payload = r.read_bytes(bytes)?.to_owned(),
|
||||
Ok(42) => msg.signature = r.read_bytes(bytes)?.to_owned(),
|
||||
Ok(t) => { r.read_unknown(bytes, t)?; }
|
||||
Err(e) => return Err(e),
|
||||
}
|
||||
}
|
||||
Ok(msg)
|
||||
}
|
||||
}
|
||||
|
||||
impl MessageWrite for Envelope {
|
||||
fn get_size(&self) -> usize {
|
||||
0
|
||||
+ self.public_key.as_ref().map_or(0, |m| 1 + sizeof_len((m).get_size()))
|
||||
+ if self.payload_type.is_empty() { 0 } else { 1 + sizeof_len((&self.payload_type).len()) }
|
||||
+ if self.payload.is_empty() { 0 } else { 1 + sizeof_len((&self.payload).len()) }
|
||||
+ if self.signature.is_empty() { 0 } else { 1 + sizeof_len((&self.signature).len()) }
|
||||
}
|
||||
|
||||
fn write_message<W: WriterBackend>(&self, w: &mut Writer<W>) -> Result<()> {
|
||||
if let Some(ref s) = self.public_key { w.write_with_tag(10, |w| w.write_message(s))?; }
|
||||
if !self.payload_type.is_empty() { w.write_with_tag(18, |w| w.write_bytes(&**&self.payload_type))?; }
|
||||
if !self.payload.is_empty() { w.write_with_tag(26, |w| w.write_bytes(&**&self.payload))?; }
|
||||
if !self.signature.is_empty() { w.write_with_tag(42, |w| w.write_bytes(&**&self.signature))?; }
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
125
core/src/generated/keys_proto.rs
Normal file
125
core/src/generated/keys_proto.rs
Normal file
@ -0,0 +1,125 @@
|
||||
// Automatically generated rust module for 'keys.proto' file
|
||||
|
||||
#![allow(non_snake_case)]
|
||||
#![allow(non_upper_case_globals)]
|
||||
#![allow(non_camel_case_types)]
|
||||
#![allow(unused_imports)]
|
||||
#![allow(unknown_lints)]
|
||||
#![allow(clippy::all)]
|
||||
#![cfg_attr(rustfmt, rustfmt_skip)]
|
||||
|
||||
|
||||
use quick_protobuf::{MessageInfo, MessageRead, MessageWrite, BytesReader, Writer, WriterBackend, Result};
|
||||
use quick_protobuf::sizeofs::*;
|
||||
use super::*;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
||||
pub enum KeyType {
|
||||
RSA = 0,
|
||||
Ed25519 = 1,
|
||||
Secp256k1 = 2,
|
||||
ECDSA = 3,
|
||||
}
|
||||
|
||||
impl Default for KeyType {
|
||||
fn default() -> Self {
|
||||
KeyType::RSA
|
||||
}
|
||||
}
|
||||
|
||||
impl From<i32> for KeyType {
|
||||
fn from(i: i32) -> Self {
|
||||
match i {
|
||||
0 => KeyType::RSA,
|
||||
1 => KeyType::Ed25519,
|
||||
2 => KeyType::Secp256k1,
|
||||
3 => KeyType::ECDSA,
|
||||
_ => Self::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a str> for KeyType {
|
||||
fn from(s: &'a str) -> Self {
|
||||
match s {
|
||||
"RSA" => KeyType::RSA,
|
||||
"Ed25519" => KeyType::Ed25519,
|
||||
"Secp256k1" => KeyType::Secp256k1,
|
||||
"ECDSA" => KeyType::ECDSA,
|
||||
_ => Self::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Debug, Default, PartialEq, Clone)]
|
||||
pub struct PublicKey {
|
||||
pub Type: keys_proto::KeyType,
|
||||
pub Data: Vec<u8>,
|
||||
}
|
||||
|
||||
impl<'a> MessageRead<'a> for PublicKey {
|
||||
fn from_reader(r: &mut BytesReader, bytes: &'a [u8]) -> Result<Self> {
|
||||
let mut msg = Self::default();
|
||||
while !r.is_eof() {
|
||||
match r.next_tag(bytes) {
|
||||
Ok(8) => msg.Type = r.read_enum(bytes)?,
|
||||
Ok(18) => msg.Data = r.read_bytes(bytes)?.to_owned(),
|
||||
Ok(t) => { r.read_unknown(bytes, t)?; }
|
||||
Err(e) => return Err(e),
|
||||
}
|
||||
}
|
||||
Ok(msg)
|
||||
}
|
||||
}
|
||||
|
||||
impl MessageWrite for PublicKey {
|
||||
fn get_size(&self) -> usize {
|
||||
0
|
||||
+ 1 + sizeof_varint(*(&self.Type) as u64)
|
||||
+ 1 + sizeof_len((&self.Data).len())
|
||||
}
|
||||
|
||||
fn write_message<W: WriterBackend>(&self, w: &mut Writer<W>) -> Result<()> {
|
||||
w.write_with_tag(8, |w| w.write_enum(*&self.Type as i32))?;
|
||||
w.write_with_tag(18, |w| w.write_bytes(&**&self.Data))?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Debug, Default, PartialEq, Clone)]
|
||||
pub struct PrivateKey {
|
||||
pub Type: keys_proto::KeyType,
|
||||
pub Data: Vec<u8>,
|
||||
}
|
||||
|
||||
impl<'a> MessageRead<'a> for PrivateKey {
|
||||
fn from_reader(r: &mut BytesReader, bytes: &'a [u8]) -> Result<Self> {
|
||||
let mut msg = Self::default();
|
||||
while !r.is_eof() {
|
||||
match r.next_tag(bytes) {
|
||||
Ok(8) => msg.Type = r.read_enum(bytes)?,
|
||||
Ok(18) => msg.Data = r.read_bytes(bytes)?.to_owned(),
|
||||
Ok(t) => { r.read_unknown(bytes, t)?; }
|
||||
Err(e) => return Err(e),
|
||||
}
|
||||
}
|
||||
Ok(msg)
|
||||
}
|
||||
}
|
||||
|
||||
impl MessageWrite for PrivateKey {
|
||||
fn get_size(&self) -> usize {
|
||||
0
|
||||
+ 1 + sizeof_varint(*(&self.Type) as u64)
|
||||
+ 1 + sizeof_len((&self.Data).len())
|
||||
}
|
||||
|
||||
fn write_message<W: WriterBackend>(&self, w: &mut Writer<W>) -> Result<()> {
|
||||
w.write_with_tag(8, |w| w.write_enum(*&self.Type as i32))?;
|
||||
w.write_with_tag(18, |w| w.write_bytes(&**&self.Data))?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
4
core/src/generated/mod.rs
Normal file
4
core/src/generated/mod.rs
Normal file
@ -0,0 +1,4 @@
|
||||
// Automatically generated mod.rs
|
||||
pub mod envelope_proto;
|
||||
pub mod keys_proto;
|
||||
pub mod peer_record_proto;
|
93
core/src/generated/peer_record_proto.rs
Normal file
93
core/src/generated/peer_record_proto.rs
Normal file
@ -0,0 +1,93 @@
|
||||
// Automatically generated rust module for 'peer_record.proto' file
|
||||
|
||||
#![allow(non_snake_case)]
|
||||
#![allow(non_upper_case_globals)]
|
||||
#![allow(non_camel_case_types)]
|
||||
#![allow(unused_imports)]
|
||||
#![allow(unknown_lints)]
|
||||
#![allow(clippy::all)]
|
||||
#![cfg_attr(rustfmt, rustfmt_skip)]
|
||||
|
||||
|
||||
use quick_protobuf::{MessageInfo, MessageRead, MessageWrite, BytesReader, Writer, WriterBackend, Result};
|
||||
use quick_protobuf::sizeofs::*;
|
||||
use super::*;
|
||||
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Debug, Default, PartialEq, Clone)]
|
||||
pub struct PeerRecord {
|
||||
pub peer_id: Vec<u8>,
|
||||
pub seq: u64,
|
||||
pub addresses: Vec<peer_record_proto::mod_PeerRecord::AddressInfo>,
|
||||
}
|
||||
|
||||
impl<'a> MessageRead<'a> for PeerRecord {
|
||||
fn from_reader(r: &mut BytesReader, bytes: &'a [u8]) -> Result<Self> {
|
||||
let mut msg = Self::default();
|
||||
while !r.is_eof() {
|
||||
match r.next_tag(bytes) {
|
||||
Ok(10) => msg.peer_id = r.read_bytes(bytes)?.to_owned(),
|
||||
Ok(16) => msg.seq = r.read_uint64(bytes)?,
|
||||
Ok(26) => msg.addresses.push(r.read_message::<peer_record_proto::mod_PeerRecord::AddressInfo>(bytes)?),
|
||||
Ok(t) => { r.read_unknown(bytes, t)?; }
|
||||
Err(e) => return Err(e),
|
||||
}
|
||||
}
|
||||
Ok(msg)
|
||||
}
|
||||
}
|
||||
|
||||
impl MessageWrite for PeerRecord {
|
||||
fn get_size(&self) -> usize {
|
||||
0
|
||||
+ if self.peer_id.is_empty() { 0 } else { 1 + sizeof_len((&self.peer_id).len()) }
|
||||
+ if self.seq == 0u64 { 0 } else { 1 + sizeof_varint(*(&self.seq) as u64) }
|
||||
+ self.addresses.iter().map(|s| 1 + sizeof_len((s).get_size())).sum::<usize>()
|
||||
}
|
||||
|
||||
fn write_message<W: WriterBackend>(&self, w: &mut Writer<W>) -> Result<()> {
|
||||
if !self.peer_id.is_empty() { w.write_with_tag(10, |w| w.write_bytes(&**&self.peer_id))?; }
|
||||
if self.seq != 0u64 { w.write_with_tag(16, |w| w.write_uint64(*&self.seq))?; }
|
||||
for s in &self.addresses { w.write_with_tag(26, |w| w.write_message(s))?; }
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub mod mod_PeerRecord {
|
||||
|
||||
use super::*;
|
||||
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Debug, Default, PartialEq, Clone)]
|
||||
pub struct AddressInfo {
|
||||
pub multiaddr: Vec<u8>,
|
||||
}
|
||||
|
||||
impl<'a> MessageRead<'a> for AddressInfo {
|
||||
fn from_reader(r: &mut BytesReader, bytes: &'a [u8]) -> Result<Self> {
|
||||
let mut msg = Self::default();
|
||||
while !r.is_eof() {
|
||||
match r.next_tag(bytes) {
|
||||
Ok(10) => msg.multiaddr = r.read_bytes(bytes)?.to_owned(),
|
||||
Ok(t) => { r.read_unknown(bytes, t)?; }
|
||||
Err(e) => return Err(e),
|
||||
}
|
||||
}
|
||||
Ok(msg)
|
||||
}
|
||||
}
|
||||
|
||||
impl MessageWrite for AddressInfo {
|
||||
fn get_size(&self) -> usize {
|
||||
0
|
||||
+ if self.multiaddr.is_empty() { 0 } else { 1 + sizeof_len((&self.multiaddr).len()) }
|
||||
}
|
||||
|
||||
fn write_message<W: WriterBackend>(&self, w: &mut Writer<W>) -> Result<()> {
|
||||
if !self.multiaddr.is_empty() { w.write_with_tag(10, |w| w.write_bytes(&**&self.multiaddr))?; }
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -43,7 +43,8 @@ pub mod secp256k1;
|
||||
pub mod error;
|
||||
|
||||
use self::error::*;
|
||||
use crate::{keys_proto, PeerId};
|
||||
use crate::{proto, PeerId};
|
||||
use quick_protobuf::{BytesReader, Writer};
|
||||
use std::convert::{TryFrom, TryInto};
|
||||
|
||||
/// Identity keypair of a node.
|
||||
@ -147,12 +148,12 @@ impl Keypair {
|
||||
|
||||
/// Encode a private key as protobuf structure.
|
||||
pub fn to_protobuf_encoding(&self) -> Result<Vec<u8>, DecodingError> {
|
||||
use prost::Message;
|
||||
use quick_protobuf::MessageWrite;
|
||||
|
||||
let pk = match self {
|
||||
Self::Ed25519(data) => keys_proto::PrivateKey {
|
||||
r#type: keys_proto::KeyType::Ed25519.into(),
|
||||
data: data.encode().into(),
|
||||
Self::Ed25519(data) => proto::PrivateKey {
|
||||
Type: proto::KeyType::Ed25519,
|
||||
Data: data.encode().to_vec(),
|
||||
},
|
||||
#[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
|
||||
Self::Rsa(_) => return Err(DecodingError::encoding_unsupported("RSA")),
|
||||
@ -162,35 +163,38 @@ impl Keypair {
|
||||
Self::Ecdsa(_) => return Err(DecodingError::encoding_unsupported("ECDSA")),
|
||||
};
|
||||
|
||||
Ok(pk.encode_to_vec())
|
||||
let mut buf = Vec::with_capacity(pk.get_size());
|
||||
let mut writer = Writer::new(&mut buf);
|
||||
pk.write_message(&mut writer).expect("Encoding to succeed");
|
||||
|
||||
Ok(buf)
|
||||
}
|
||||
|
||||
/// 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;
|
||||
use quick_protobuf::MessageRead;
|
||||
|
||||
let mut private_key = keys_proto::PrivateKey::decode(bytes)
|
||||
let mut reader = BytesReader::from_bytes(bytes);
|
||||
let mut private_key = proto::PrivateKey::from_reader(&mut reader, bytes)
|
||||
.map_err(|e| DecodingError::bad_protobuf("private key bytes", e))
|
||||
.map(zeroize::Zeroizing::new)?;
|
||||
|
||||
let key_type = keys_proto::KeyType::from_i32(private_key.r#type)
|
||||
.ok_or_else(|| DecodingError::unknown_key_type(private_key.r#type))?;
|
||||
|
||||
match key_type {
|
||||
keys_proto::KeyType::Ed25519 => {
|
||||
ed25519::Keypair::decode(&mut private_key.data).map(Keypair::Ed25519)
|
||||
match private_key.Type {
|
||||
proto::KeyType::Ed25519 => {
|
||||
ed25519::Keypair::decode(&mut private_key.Data).map(Keypair::Ed25519)
|
||||
}
|
||||
keys_proto::KeyType::Rsa => Err(DecodingError::decoding_unsupported("RSA")),
|
||||
keys_proto::KeyType::Secp256k1 => Err(DecodingError::decoding_unsupported("secp256k1")),
|
||||
keys_proto::KeyType::Ecdsa => Err(DecodingError::decoding_unsupported("ECDSA")),
|
||||
proto::KeyType::RSA => Err(DecodingError::decoding_unsupported("RSA")),
|
||||
proto::KeyType::Secp256k1 => Err(DecodingError::decoding_unsupported("secp256k1")),
|
||||
proto::KeyType::ECDSA => Err(DecodingError::decoding_unsupported("ECDSA")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl zeroize::Zeroize for keys_proto::PrivateKey {
|
||||
impl zeroize::Zeroize for proto::PrivateKey {
|
||||
fn zeroize(&mut self) {
|
||||
self.r#type.zeroize();
|
||||
self.data.zeroize();
|
||||
// KeyType cannot be zeroized.
|
||||
self.Type = proto::KeyType::default();
|
||||
self.Data.zeroize();
|
||||
}
|
||||
}
|
||||
|
||||
@ -232,23 +236,27 @@ 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;
|
||||
use quick_protobuf::MessageWrite;
|
||||
|
||||
let public_key = keys_proto::PublicKey::from(self);
|
||||
let public_key = proto::PublicKey::from(self);
|
||||
|
||||
let mut buf = Vec::with_capacity(public_key.encoded_len());
|
||||
let mut buf = Vec::with_capacity(public_key.get_size());
|
||||
let mut writer = Writer::new(&mut buf);
|
||||
public_key
|
||||
.encode(&mut buf)
|
||||
.expect("Vec<u8> provides capacity as needed");
|
||||
.write_message(&mut writer)
|
||||
.expect("Encoding to succeed");
|
||||
|
||||
buf
|
||||
}
|
||||
|
||||
/// 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;
|
||||
use quick_protobuf::MessageRead;
|
||||
|
||||
let pubkey = keys_proto::PublicKey::decode(bytes)
|
||||
let mut reader = BytesReader::from_bytes(bytes);
|
||||
|
||||
let pubkey = proto::PublicKey::from_reader(&mut reader, bytes)
|
||||
.map_err(|e| DecodingError::bad_protobuf("public key bytes", e))?;
|
||||
|
||||
pubkey.try_into()
|
||||
@ -260,67 +268,62 @@ impl PublicKey {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&PublicKey> for keys_proto::PublicKey {
|
||||
impl From<&PublicKey> for 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(),
|
||||
PublicKey::Ed25519(key) => proto::PublicKey {
|
||||
Type: proto::KeyType::Ed25519,
|
||||
Data: 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(),
|
||||
PublicKey::Rsa(key) => proto::PublicKey {
|
||||
Type: proto::KeyType::RSA,
|
||||
Data: 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(),
|
||||
PublicKey::Secp256k1(key) => proto::PublicKey {
|
||||
Type: proto::KeyType::Secp256k1,
|
||||
Data: 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(),
|
||||
PublicKey::Ecdsa(key) => proto::PublicKey {
|
||||
Type: proto::KeyType::ECDSA,
|
||||
Data: key.encode_der(),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<keys_proto::PublicKey> for PublicKey {
|
||||
impl TryFrom<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::unknown_key_type(pubkey.r#type))?;
|
||||
|
||||
match key_type {
|
||||
keys_proto::KeyType::Ed25519 => {
|
||||
ed25519::PublicKey::decode(&pubkey.data).map(PublicKey::Ed25519)
|
||||
fn try_from(pubkey: proto::PublicKey) -> Result<Self, Self::Error> {
|
||||
match pubkey.Type {
|
||||
proto::KeyType::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)
|
||||
}
|
||||
proto::KeyType::RSA => rsa::PublicKey::decode_x509(&pubkey.Data).map(PublicKey::Rsa),
|
||||
#[cfg(any(not(feature = "rsa"), target_arch = "wasm32"))]
|
||||
keys_proto::KeyType::Rsa => {
|
||||
proto::KeyType::RSA => {
|
||||
log::debug!("support for RSA was disabled at compile-time");
|
||||
Err(DecodingError::missing_feature("rsa"))
|
||||
}
|
||||
#[cfg(feature = "secp256k1")]
|
||||
keys_proto::KeyType::Secp256k1 => {
|
||||
secp256k1::PublicKey::decode(&pubkey.data).map(PublicKey::Secp256k1)
|
||||
proto::KeyType::Secp256k1 => {
|
||||
secp256k1::PublicKey::decode(&pubkey.Data).map(PublicKey::Secp256k1)
|
||||
}
|
||||
#[cfg(not(feature = "secp256k1"))]
|
||||
keys_proto::KeyType::Secp256k1 => {
|
||||
proto::KeyType::Secp256k1 => {
|
||||
log::debug!("support for secp256k1 was disabled at compile-time");
|
||||
Err(DecodingError::missing_feature("secp256k1"))
|
||||
}
|
||||
#[cfg(feature = "ecdsa")]
|
||||
keys_proto::KeyType::Ecdsa => {
|
||||
ecdsa::PublicKey::decode_der(&pubkey.data).map(PublicKey::Ecdsa)
|
||||
proto::KeyType::ECDSA => {
|
||||
ecdsa::PublicKey::decode_der(&pubkey.Data).map(PublicKey::Ecdsa)
|
||||
}
|
||||
#[cfg(not(feature = "ecdsa"))]
|
||||
keys_proto::KeyType::Ecdsa => {
|
||||
proto::KeyType::ECDSA => {
|
||||
log::debug!("support for ECDSA was disabled at compile-time");
|
||||
Err(DecodingError::missing_feature("ecdsa"))
|
||||
}
|
||||
|
@ -68,13 +68,6 @@ impl DecodingError {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn unknown_key_type(key_type: i32) -> Self {
|
||||
Self {
|
||||
msg: format!("unknown key-type {key_type}"),
|
||||
source: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn decoding_unsupported(key_type: &'static str) -> Self {
|
||||
Self {
|
||||
msg: format!("decoding {key_type} key from Protobuf is unsupported"),
|
||||
|
@ -37,22 +37,18 @@
|
||||
|
||||
#![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 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"));
|
||||
mod proto {
|
||||
include!("generated/mod.rs");
|
||||
pub use self::{
|
||||
envelope_proto::*, keys_proto::*, peer_record_proto::mod_PeerRecord::*,
|
||||
peer_record_proto::PeerRecord,
|
||||
};
|
||||
}
|
||||
|
||||
/// Multi-address re-export.
|
||||
pub use multiaddr;
|
||||
use std::fmt;
|
||||
use std::fmt::Formatter;
|
||||
pub type Negotiated<T> = multistream_select::Negotiated<T>;
|
||||
|
||||
mod peer_id;
|
||||
@ -80,6 +76,17 @@ pub use translation::address_translation;
|
||||
pub use transport::Transport;
|
||||
pub use upgrade::{InboundUpgrade, OutboundUpgrade, ProtocolName, UpgradeError, UpgradeInfo};
|
||||
|
||||
#[derive(thiserror::Error, Debug)]
|
||||
#[error(transparent)]
|
||||
pub struct DecodeError(prost::DecodeError);
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub struct DecodeError(String);
|
||||
|
||||
impl From<quick_protobuf::Error> for DecodeError {
|
||||
fn from(e: quick_protobuf::Error) -> Self {
|
||||
Self(e.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for DecodeError {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{}", self.0)
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,10 @@
|
||||
use crate::identity::error::SigningError;
|
||||
use crate::identity::Keypair;
|
||||
use crate::proto;
|
||||
use crate::signed_envelope::SignedEnvelope;
|
||||
use crate::{peer_record_proto, signed_envelope, DecodeError, Multiaddr, PeerId};
|
||||
use crate::{signed_envelope, DecodeError, Multiaddr, PeerId};
|
||||
use instant::SystemTime;
|
||||
use quick_protobuf::{BytesReader, Writer};
|
||||
use std::convert::TryInto;
|
||||
|
||||
const PAYLOAD_TYPE: &str = "/libp2p/routing-state-record";
|
||||
@ -29,11 +31,13 @@ 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;
|
||||
use quick_protobuf::MessageRead;
|
||||
|
||||
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).map_err(DecodeError)?;
|
||||
let mut reader = BytesReader::from_bytes(payload);
|
||||
let record =
|
||||
proto::PeerRecord::from_reader(&mut reader, payload).map_err(DecodeError::from)?;
|
||||
|
||||
let peer_id = PeerId::from_bytes(&record.peer_id)?;
|
||||
|
||||
@ -45,7 +49,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 {
|
||||
@ -60,7 +64,7 @@ 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;
|
||||
use quick_protobuf::MessageWrite;
|
||||
|
||||
let seq = SystemTime::now()
|
||||
.duration_since(SystemTime::UNIX_EPOCH)
|
||||
@ -69,21 +73,23 @@ impl PeerRecord {
|
||||
let peer_id = key.public().to_peer_id();
|
||||
|
||||
let payload = {
|
||||
let record = peer_record_proto::PeerRecord {
|
||||
let record = proto::PeerRecord {
|
||||
peer_id: peer_id.to_bytes(),
|
||||
seq,
|
||||
addresses: addresses
|
||||
.iter()
|
||||
.map(|m| peer_record_proto::peer_record::AddressInfo {
|
||||
.map(|m| proto::AddressInfo {
|
||||
multiaddr: m.to_vec(),
|
||||
})
|
||||
.collect(),
|
||||
};
|
||||
|
||||
let mut buf = Vec::with_capacity(record.encoded_len());
|
||||
let mut buf = Vec::with_capacity(record.get_size());
|
||||
let mut writer = Writer::new(&mut buf);
|
||||
record
|
||||
.encode(&mut buf)
|
||||
.expect("Vec<u8> provides capacity as needed");
|
||||
.write_message(&mut writer)
|
||||
.expect("Encoding to succeed");
|
||||
|
||||
buf
|
||||
};
|
||||
|
||||
@ -162,7 +168,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn mismatched_signature() {
|
||||
use prost::Message;
|
||||
use quick_protobuf::MessageWrite;
|
||||
|
||||
let addr: Multiaddr = HOME.parse().unwrap();
|
||||
|
||||
@ -171,18 +177,20 @@ mod tests {
|
||||
let identity_b = Keypair::generate_ed25519();
|
||||
|
||||
let payload = {
|
||||
let record = peer_record_proto::PeerRecord {
|
||||
let record = proto::PeerRecord {
|
||||
peer_id: identity_a.public().to_peer_id().to_bytes(),
|
||||
seq: 0,
|
||||
addresses: vec![peer_record_proto::peer_record::AddressInfo {
|
||||
addresses: vec![proto::AddressInfo {
|
||||
multiaddr: addr.to_vec(),
|
||||
}],
|
||||
};
|
||||
|
||||
let mut buf = Vec::with_capacity(record.encoded_len());
|
||||
let mut buf = Vec::with_capacity(record.get_size());
|
||||
let mut writer = Writer::new(&mut buf);
|
||||
record
|
||||
.encode(&mut buf)
|
||||
.expect("Vec<u8> provides capacity as needed");
|
||||
.write_message(&mut writer)
|
||||
.expect("Encoding to succeed");
|
||||
|
||||
buf
|
||||
};
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
use crate::identity::error::SigningError;
|
||||
use crate::identity::Keypair;
|
||||
use crate::{identity, DecodeError, PublicKey};
|
||||
use crate::{identity, proto, DecodeError, PublicKey};
|
||||
use quick_protobuf::{BytesReader, Writer};
|
||||
use std::convert::TryInto;
|
||||
use std::fmt;
|
||||
use unsigned_varint::encode::usize_buffer;
|
||||
@ -73,37 +74,41 @@ impl SignedEnvelope {
|
||||
|
||||
/// Encode this [`SignedEnvelope`] using the protobuf encoding specified in the RFC.
|
||||
pub fn into_protobuf_encoding(self) -> Vec<u8> {
|
||||
use prost::Message;
|
||||
use quick_protobuf::MessageWrite;
|
||||
|
||||
let envelope = crate::envelope_proto::Envelope {
|
||||
let envelope = proto::Envelope {
|
||||
public_key: Some((&self.key).into()),
|
||||
payload_type: self.payload_type,
|
||||
payload: self.payload,
|
||||
signature: self.signature,
|
||||
};
|
||||
|
||||
let mut buf = Vec::with_capacity(envelope.encoded_len());
|
||||
let mut buf = Vec::with_capacity(envelope.get_size());
|
||||
let mut writer = Writer::new(&mut buf);
|
||||
|
||||
envelope
|
||||
.encode(&mut buf)
|
||||
.expect("Vec<u8> provides capacity as needed");
|
||||
.write_message(&mut writer)
|
||||
.expect("Encoding to succeed");
|
||||
|
||||
buf
|
||||
}
|
||||
|
||||
/// Decode a [`SignedEnvelope`] using the protobuf encoding specified in the RFC.
|
||||
pub fn from_protobuf_encoding(bytes: &[u8]) -> Result<Self, DecodingError> {
|
||||
use prost::Message;
|
||||
use quick_protobuf::MessageRead;
|
||||
|
||||
let envelope = crate::envelope_proto::Envelope::decode(bytes).map_err(DecodeError)?;
|
||||
let mut reader = BytesReader::from_bytes(bytes);
|
||||
let envelope =
|
||||
proto::Envelope::from_reader(&mut reader, bytes).map_err(DecodeError::from)?;
|
||||
|
||||
Ok(Self {
|
||||
key: envelope
|
||||
.public_key
|
||||
.ok_or(DecodingError::MissingPublicKey)?
|
||||
.try_into()?,
|
||||
payload_type: envelope.payload_type,
|
||||
payload: envelope.payload,
|
||||
signature: envelope.signature,
|
||||
payload_type: envelope.payload_type.to_vec(),
|
||||
payload: envelope.payload.to_vec(),
|
||||
signature: envelope.signature.to_vec(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user