-
Notifications
You must be signed in to change notification settings - Fork 964
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Migrate from protoc to rust-protobuf #3050
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for tackling this! Very appreciated!
I left a few questions.
@@ -129,7 +126,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(protobuf::Error), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this part of the public API? If yes, then this is actually a breaking change which is unfortunate :/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh I missed that. Yes, it is part of the public API 😞.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Damn okay. Well don't worry about it here for now, I'll send a PR that wraps the error here. That is still a breaking change but we can ship that separately!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So my idea here is to make a dedicated error like this:
#[derive(thiserror::Error, Debug)]
#[error(transparent)]
pub struct DecodeError(protobuf::Error)
This preserves the source chain but hides the concrete error type from the public API.
It'd be nice to do this in a separate PR and then put this feature on top of that. Let me know if you'd be happy to do that otherwise I'll try to get to that next week!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So my idea here is to make a dedicated error like this:
#[derive(thiserror::Error, Debug)] #[error(transparent)] pub struct DecodeError(protobuf::Error)This preserves the source chain but hides the concrete error type from the public API.
That sounds good!
It'd be nice to do this in a separate PR and then put this feature on top of that. Let me know if you'd be happy to do that otherwise I'll try to get to that next week!
If you could please do that that would be great! I'll rebase once that is merged.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I starting working on this here: #3058
38b7e97
to
f1f6ee4
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
core/build.rs
Outdated
.unwrap(); | ||
] | ||
) | ||
.customize(cust.lite_runtime(true)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All the builder fns take self
so I think we can just do this:
.customize(cust.lite_runtime(true)) | |
.customize(protobuf_codegen::Customize::default().lite_runtime(true)) |
core/src/identity.rs
Outdated
.encode(&mut buf) | ||
.expect("Vec<u8> provides capacity as needed"); | ||
buf | ||
public_key.write_to_bytes().expect("Encoding failed.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we say something like "all fields to be initialized" given that's the invariant we are relying on?
@@ -28,7 +28,7 @@ pub enum PlainTextError { | |||
IoError(IoError), | |||
|
|||
/// Failed to parse the handshake protobuf message. | |||
InvalidPayload(Option<prost::DecodeError>), | |||
InvalidPayload(Option<protobuf::Error>), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This makes it a breaking change too I think.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it's public.
I kicked CI, seems there are still a couple of compile errors 😊 |
Yes, I need to clean up a few tests. Will fix. |
@@ -13,9 +13,6 @@ categories = ["asynchronous"] | |||
[dependencies] | |||
asynchronous-codec = { version = "0.6" } | |||
bytes = { version = "1" } | |||
prost = "0.11" | |||
protobuf = "3.2" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't really a prost-codec
anymore, now that we are replacing the implementation with protobuf
😅
@mxinden Should we publish a new crate?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
7f7e110
to
cb1ffbb
Compare
I think there is one crate left to do. I should have time to do it tomorrow and also take care of some of the other pending tasks. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Only a few minor comments!
Looking forward to the full solution :)
First off, thanks @kckeiks for the work here. This will make using rust-libp2p for newcomers so much easier. Given that Protobuf is at the core of libp2p, performance is relevant. Are there any comparisons to prost you can point me to @thomaseizinger @kckeiks? Let's make sure to test this, e.g. via a large user, before merging here. |
cb1ffbb
to
5e7eb2c
Compare
The method write_to_bytes only fails when writting a proto2 message with missing required fields.
5e7eb2c
to
fb7e6db
Compare
👍
quick-proto has some performance comparisons of |
I fixed the tests. |
|
Thank you for running those tests @jxs ! |
@kckeiks Please decide if you want to amend commits and force-push or never force-push at all :) We squash merge in the end so the commits will be gone anyway. But reviews can sometimes be easier by amending commits later but that is also not happening here: For example 8acaa31 would need to be squashed into ea8a303. Force-pushing but not amending commits is kind of the worst of both worlds: I can't see a clear diff from the last push but the commits also overlap, making it hard to review patch-by-patch :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
A few more comments, plus the CI workflow needs adjusting to remove the installation of protoc
!
@@ -174,32 +176,33 @@ impl Keypair { | |||
} | |||
}; | |||
|
|||
Ok(pk.encode_to_vec()) | |||
Ok(pk.write_to_bytes().map_err(|e| DecodingError::new("Failed to decode.").source(e))?) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We discovered that this can never fail right? Let's panic here for consistency.
pk.write_to_bytes() | ||
.map_err(|e| DecodingError::new("Failed to decode.").source(e)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please panic here for consistency.
let key_type = | ||
keys_proto::KeyType::from_i32(private_key.Type().value()).ok_or_else(|| { | ||
DecodingError::new(format!("unknown key type: {:?}", private_key.Type())) | ||
})?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like another round-trip to me? Wouldn't Type()
already give you the enum value?
|
||
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::parse_from_bytes(payload) | ||
.map_err(FromEnvelopeError::from)?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need the map_err
now?
m.msg_sent(&topic_hash, msg_bytes); | ||
m.msg_sent( | ||
&topic_hash, | ||
usize::try_from(msg_bytes).expect("Size of sent messages fit in usize."), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we panic here, we might as well also panic on line 621.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think as regular cast could do as well.
Those relative numbers aren't exactly great. I'd be willing to take that hit though for the removal of the |
Sorry, I've been relying on my command history too much while amending and force-pushing so I inadvertently force-pushed. I will cut that out 😸 . |
Any thoughts on using |
Can you share an example of what |
yeah agree Thomas.
|
This PR #3066 uses |
Description
Closes #3024.
Fixes #2645.
Links to any relevant issues
Open Questions
I updated core and a couple of other packages. This is wip atm but I'll update the remaining crates this week.
Change checklist