Change the signature of consensus_encode to return io::Error's #494
Change the signature of consensus_encode to return io::Error's #494elichai merged 1 commit intorust-bitcoin:masterfrom
Conversation
|
Nice! I think this should get its own version bump, separate from other changes, because it requires some invasive but mechanical changes for downstream users. |
src/network/message.rs
Outdated
There was a problem hiding this comment.
Some methods rely on FromStr implementation to do a conversion; for instance if use clap for parsing commands from command-line parameters (which may be a case for cli tools operating with bitcoin P2P network). So I propose also to add impl FromStr for CommandString and from it call this method directly
Can it not just go with the next breaking version bump? I mean it doesn't really matter if it has it's own bump, right? At some point people will have to do it if they want to keep updating. |
108528f to
446553d
Compare
src/network/message.rs
Outdated
There was a problem hiding this comment.
Trying to understand why this and above are depricated. The message will be really surprising in practice: instead of something.from() users are asked to use something::<CommandString>.from(), but even that is not clear from the message... Because in most cases method is called on the object, without additional qualifiers, and it will be up to the compiler to decide wich implementation to call.
It seams reasonable just to remove this methods, and nothing bad will happen.
There was a problem hiding this comment.
Yeah I removed it. I pushed a new commit cleaning up the CommandString API.
src/network/message.rs
Outdated
There was a problem hiding this comment.
I don't like this, I'd rather remove the From impl or panic here then do unexpected things
There was a problem hiding this comment.
oh I see you deprecated it, hmm idk what's the right thing to do
also, deprecating a trait impl doesn't do anything UX wise:
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=c67bc53c2372c636208adbfab79fa02e
rust-lang/rust#39935
There was a problem hiding this comment.
Hmm, that seems to be a cargo bug. I would prefer not to panic, so perhaps just removing the method is the best option.
There was a problem hiding this comment.
K I pushed a new commit that cleans up the CommandString API. I thin it's such a infrequently used type that all the fancy construction methods are not needed. So I removed all of them.
src/network/message.rs
Outdated
There was a problem hiding this comment.
You're saying don't call CommandString::from to avoid allocating but you then call to_owned() which allocates?
There was a problem hiding this comment.
Hmm, that might have been related to an earlier version of the impl or wrongly formulated.. I don't remember. I think we can't use CommandString::from because &'a str doesn't implement Into<Cow<'static, str>>, but I'm not sure, let me try.
Ah k so
72 | Ok(CommandString(s.into()))
| ^^^^^^^^
= note: expected `std::borrow::Cow<'static, _>`
found `std::borrow::Cow<'_, _>`
I was right, and I don't know what to do here :| I'd be in favor of dropping FromStr as well for this type and just have the basic constructor which has Into<Cow<..>>.
464196c to
9c20cf8
Compare
|
Rebased and added commit to clean up the CommandString API. |
|
Just noticed this randomly and I have to say I'm not a huge fan of I don't know the exact context here, so feel free to ignore me if it's unrelated. |
Yeah I don't think that's quite related. Like currently it's about the difference between returning an Also, this PR is really neutral about |
src/network/message.rs
Outdated
There was a problem hiding this comment.
nit, Calling the function from outside the From trait is somewhat weird
There was a problem hiding this comment.
Yeah I couldn't think of a better name. I thought of create but it's quite conventional to use from or from_xxx for converter methods. I also considered just new. Open to opinions, though, don't feel strongly about this. I just thought from was good enough.
There was a problem hiding this comment.
Open to opinions
Personally, new would probably be the first thing I would look for when trying to construct one of these.
Another thing to consider might be to name it try_from given that you are returning a Result.
There was a problem hiding this comment.
According to rust API guidelines we should use with_str as a function name: https://rust-lang.github.io/api-guidelines/naming.html#casing-conforms-to-rfc-430-c-case
There was a problem hiding this comment.
I'm not sure, the guildlines say with_more_details, however in this case intput is not "more details", it's literally the source of informtion. My understanding is that with_more_details is used for special cases (with_capacity is an obvious one)
The function header also kinda leaks internal representation but I guess it's fine?
Implementing TryFrom would be best, but AFAIR it's not in supported MSRV.
9c20cf8 to
876651b
Compare
|
Rebased. |
29ab439 to
0b54429
Compare
Yes, but if we do it in the same bump as a bunch of other stuff, then they have to do these changes in a single commit alongside a bunch of other stuff. |
dr-orlovsky
left a comment
There was a problem hiding this comment.
Seems like there a few things potentially reducing stability of the software that I missed in my previous review
src/network/message.rs
Outdated
There was a problem hiding this comment.
According to rust API guidelines we should use with_str as a function name: https://rust-lang.github.io/api-guidelines/naming.html#casing-conforms-to-rfc-430-c-case
src/network/message.rs
Outdated
There was a problem hiding this comment.
This change will lead to a panic if the length of the CommandString is larger than 12. Why not to use ENAMETOOLONG io::Error equivalent?
There was a problem hiding this comment.
I don't think so. The PR removes the uncheck instantiation path for CommandString through From and replaces it with CommandString::new, which checks that the string is <=12 bytes long.
src/network/message.rs
Outdated
There was a problem hiding this comment.
This opens an attack vector to the rust-bitcoin-based software by just sending them invalid command string causing a crash
There was a problem hiding this comment.
I don't think so, the return value of .cmd() is a static string defines by the enum variant, not attacker controlled.
There was a problem hiding this comment.
I think the message in expect should say invalid. The complete message sounding like "program panicked because cmd string is valid" is strange.
sgeisler
left a comment
There was a problem hiding this comment.
This seems to be on hold for now but I really like the changes, does away with a lot of weirdness. Will do a more thorough review once it's merge-ready.
src/network/message.rs
Outdated
There was a problem hiding this comment.
I don't think so, the return value of .cmd() is a static string defines by the enum variant, not attacker controlled.
src/network/message.rs
Outdated
There was a problem hiding this comment.
I don't think so. The PR removes the uncheck instantiation path for CommandString through From and replaces it with CommandString::new, which checks that the string is <=12 bytes long.
|
Setting to 0.26 milestone. Originally we had planned to punt to 0.27 because it is an API-breaking-only change, but I this we should prioritize it since our code currently unwraps these objects whenever we encode into hash engines, for example, so it would be better to eliminate theoretical panics. On the other hand if this winds up blocking 0.26 then I'll probably move it to 0.27 :) Needs rebase. |
This is instead of encode::Errors because the encoders should not be allowed to return errors that don't originate in the writer they are writing into. This is a part of the method definition that has been relied upon for a while already.
0b54429 to
61918df
Compare
|
post-ack |
This is instead of encode::Errors because the encoders should
not be allowed to return errors that don't originate in the writer
they are writing into.
This is a part of the method definition that has been relied upon for a
while already.