*: Don't leak prost dependency in error types (#3058)

With the current design, a major version bump of `prost` leaks into
all consumers of `prost-codec`.
This commit is contained in:
Thomas Eizinger
2022-11-02 23:02:21 +11:00
committed by GitHub
parent b42f28630e
commit 71131e0622
70 changed files with 428 additions and 400 deletions

View File

@ -79,6 +79,10 @@ 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);
use std::{future::Future, pin::Pin};
/// Implemented on objects that can run a `Future` in the background.

View File

@ -1,10 +1,9 @@
use crate::identity::error::SigningError;
use crate::identity::Keypair;
use crate::signed_envelope::SignedEnvelope;
use crate::{peer_record_proto, signed_envelope, Multiaddr, PeerId};
use crate::{peer_record_proto, signed_envelope, DecodeError, Multiaddr, PeerId};
use instant::SystemTime;
use std::convert::TryInto;
use std::fmt;
const PAYLOAD_TYPE: &str = "/libp2p/routing-state-record";
const DOMAIN_SEP: &str = "libp2p-routing-state";
@ -34,7 +33,7 @@ impl PeerRecord {
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::decode(payload).map_err(DecodeError)?;
let peer_id = PeerId::from_bytes(&record.peer_id)?;
@ -124,73 +123,23 @@ impl PeerRecord {
}
}
#[derive(Debug)]
#[derive(thiserror::Error, Debug)]
pub enum FromEnvelopeError {
/// Failed to extract the payload from the envelope.
BadPayload(signed_envelope::ReadPayloadError),
#[error("Failed to extract payload from envelope")]
BadPayload(#[from] signed_envelope::ReadPayloadError),
/// Failed to decode the provided bytes as a [`PeerRecord`].
InvalidPeerRecord(prost::DecodeError),
#[error("Failed to decode bytes as PeerRecord")]
InvalidPeerRecord(#[from] DecodeError),
/// Failed to decode the peer ID.
InvalidPeerId(multihash::Error),
#[error("Failed to decode bytes as PeerId")]
InvalidPeerId(#[from] multihash::Error),
/// The signer of the envelope is different than the peer id in the record.
#[error("The signer of the envelope is different than the peer id in the record")]
MismatchedSignature,
/// Failed to decode a multi-address.
InvalidMultiaddr(multiaddr::Error),
}
impl From<signed_envelope::ReadPayloadError> for FromEnvelopeError {
fn from(e: signed_envelope::ReadPayloadError) -> Self {
Self::BadPayload(e)
}
}
impl From<prost::DecodeError> for FromEnvelopeError {
fn from(e: prost::DecodeError) -> Self {
Self::InvalidPeerRecord(e)
}
}
impl From<multihash::Error> for FromEnvelopeError {
fn from(e: multihash::Error) -> Self {
Self::InvalidPeerId(e)
}
}
impl From<multiaddr::Error> for FromEnvelopeError {
fn from(e: multiaddr::Error) -> Self {
Self::InvalidMultiaddr(e)
}
}
impl fmt::Display for FromEnvelopeError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::BadPayload(_) => write!(f, "Failed to extract payload from envelope"),
Self::InvalidPeerRecord(_) => {
write!(f, "Failed to decode bytes as PeerRecord")
}
Self::InvalidPeerId(_) => write!(f, "Failed to decode bytes as PeerId"),
Self::MismatchedSignature => write!(
f,
"The signer of the envelope is different than the peer id in the record"
),
Self::InvalidMultiaddr(_) => {
write!(f, "Failed to decode bytes as MultiAddress")
}
}
}
}
impl std::error::Error for FromEnvelopeError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Self::InvalidPeerRecord(inner) => Some(inner),
Self::InvalidPeerId(inner) => Some(inner),
Self::MismatchedSignature => None,
Self::InvalidMultiaddr(inner) => Some(inner),
Self::BadPayload(inner) => Some(inner),
}
}
#[error("Failed to decode bytes as MultiAddress")]
InvalidMultiaddr(#[from] multiaddr::Error),
}
#[cfg(test)]

View File

@ -1,6 +1,6 @@
use crate::identity::error::SigningError;
use crate::identity::Keypair;
use crate::{identity, PublicKey};
use crate::{identity, DecodeError, PublicKey};
use std::convert::TryInto;
use std::fmt;
use unsigned_varint::encode::usize_buffer;
@ -94,7 +94,7 @@ impl SignedEnvelope {
pub fn from_protobuf_encoding(bytes: &[u8]) -> Result<Self, DecodingError> {
use prost::Message;
let envelope = crate::envelope_proto::Envelope::decode(bytes)?;
let envelope = crate::envelope_proto::Envelope::decode(bytes).map_err(DecodeError)?;
Ok(Self {
key: envelope
@ -140,48 +140,19 @@ fn signature_payload(domain_separation: String, payload_type: &[u8], payload: &[
}
/// Errors that occur whilst decoding a [`SignedEnvelope`] from its byte representation.
#[derive(Debug)]
#[derive(thiserror::Error, Debug)]
pub enum DecodingError {
/// Decoding the provided bytes as a signed envelope failed.
InvalidEnvelope(prost::DecodeError),
#[error("Failed to decode envelope")]
InvalidEnvelope(#[from] DecodeError),
/// The public key in the envelope could not be converted to our internal public key type.
InvalidPublicKey(identity::error::DecodingError),
#[error("Failed to convert public key")]
InvalidPublicKey(#[from] identity::error::DecodingError),
/// The public key in the envelope could not be converted to our internal public key type.
#[error("Public key is missing from protobuf struct")]
MissingPublicKey,
}
impl From<prost::DecodeError> for DecodingError {
fn from(e: prost::DecodeError) -> Self {
Self::InvalidEnvelope(e)
}
}
impl From<identity::error::DecodingError> for DecodingError {
fn from(e: identity::error::DecodingError) -> Self {
Self::InvalidPublicKey(e)
}
}
impl fmt::Display for DecodingError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::InvalidEnvelope(_) => write!(f, "Failed to decode envelope"),
Self::InvalidPublicKey(_) => write!(f, "Failed to convert public key"),
Self::MissingPublicKey => write!(f, "Public key is missing from protobuf struct"),
}
}
}
impl std::error::Error for DecodingError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Self::InvalidEnvelope(inner) => Some(inner),
Self::InvalidPublicKey(inner) => Some(inner),
Self::MissingPublicKey => None,
}
}
}
/// Errors that occur whilst extracting the payload of a [`SignedEnvelope`].
#[derive(Debug)]
pub enum ReadPayloadError {