Make sendcmpt idempotent#6317
Conversation
Abeeujah
left a comment
There was a problem hiding this comment.
cACK ; Yeah, true, this is legit!
d008781 to
9360909
Compare
|
The annoying thing is re-writing DecoderError to return an enum instead of the default ArrayDecoder error if the bit is out of range.. |
9360909 to
1435e9e
Compare
90b8e62 to
e8bdfbf
Compare
e8bdfbf to
d5e6fd6
Compare
|
Title needs attention please. |
Thanks, fixed. |
|
Are you sure your claims about the macro not working with custom error types is correct? |
Yes, and the reason is that the macro In Notice $err is using parens |
|
Have you tried defining a #[cfg(feature = "encoding")]
crate::decoder_newtype! {
/// The decoder for the [`Amount`] type.
#[derive(Debug, Clone)]
pub struct AmountDecoder(encoding::ArrayDecoder<8>);
/// Constructs a new [`Amount`] decoder.
pub const fn new() -> Self { Self(encoding::ArrayDecoder::new()) }
fn map_push_bytes_err(e: encoding::UnexpectedEofError) -> AmountDecoderError {
AmountDecoderError::eof(e)
}
fn end(result: Result<[u8; 8], encoding::UnexpectedEofError>) -> Result<Amount, AmountDecoderError> {
let value = result.map_err(AmountDecoderError::eof)?;
let a = u64::from_le_bytes(value);
Amount::from_sat(a).map_err(AmountDecoderError::out_of_range)
}
} |
8357621 to
3f50369
Compare
Yeah, that looks like it works. Thanks for the suggestion. Need to clean it up to make it less hideous looking. Marking as draft until I have a chance to. |
243df4f to
8dae280
Compare
|
|
As best as I can tell, these fuzz tests are not using Arbitrary though, are they? It looks like the fuzz test is just generating random byte arrays "data", then calling: let old_result: Result<old_bitcoin::p2p::message_compact_blocks::SendCmpct, _> =
old_bitcoin::consensus::encode::deserialize(&data);
let new_result: Result<p2p::message_compact_blocks::SendCmpct, _> =
decode_from_slice(&data);Then comparing that if one of them creates a SendCmpt successfully, so should they both, and if one errors, so should they both. So I don't think there is any change required to any Arbitrary type. |
|
the name "old_bitcoin" is pretty funny though I think. |
|
Ah, right, the issue is that you need to backport this change to 0.32.x at the same time as you do this PR. Or you need to whitelist the change in the fuzztest. In this case I'd suggest backporting, since the change fixes our code to better match the BIP. If you just want to get this PR in without further rebase hell, you can patch the fuzztest for now but please file an issue that this needs a backport (and the fuzz patch removed). |
Right, that's exactly what I said a few weeks ago:
Anyway, I agree that this change should be back-ported to 0.32.x, particularly since it's also being patched in core and btcd. Will circle back on this when I have a chance to. |
|
Ok so I see #6457 in flight. Lets just change it there for 0.32.x? I realize that this might require fiddling with scripts and API text files, and I want to be upfront that I would prefer not to deal with rebasing and conflict that goes with dealing the the API text files. Lately with my projects I add files to the examples directory so that I don't accidentally break the API. I realize a project as large as rust-bitcoin can't possibly have an example to use every API, however, I don't think a txt file would help me much from accidentally changing the API. Generally, I find reading the code to more informative than the giant wall of txt files.. Also I don't like feeling like the bad guy that doesn't want to fiddle with the files, by my time is my own, and my contributions are not under any coercion. I mean, if someone wants to send me some sats to run scripts and fiddle with API text files all day then maybe :P. Just want to avoid the conflict that has arisen in the past when I've put in a PR that requires dealing with these files. |
|
#6457 is merged and does not have this PR's change in it. So we will need a separate backport, sorry. Assuming this gets in. I appreciate that you don't care to deal with API files, but this PR does not change any API surface.
For future reference, when you post correct comments like "this has nothing to do with |
I understand that. That's one of the reasons I still contribute to this crate. There are other changes I'd like to see get in, for example: #6439, although I try not to pickup PRs that will cause the need for fussing with API txt files. The reason I bring it up here is that creating a backport will need to fuss with txt files I presume.
If you review the order of the conversation, please notice that I said "correct comment" long before "provocative comment about API files", so I don't think you can blame that on the reason this PR has been ignored. From what i've observed, this PR is ignored because nobody seems to care about maintaining this crate. You didn't bother to take the time to see if your hunch about Arbitrary causing the problem was correct, probably because you're overstretched with other more pressing issues. The other "maintainers" seem to not care either. Neither Nick nor Rob ever seem to comment unless prompted and Tobin doesn't seemed to want to be bothered with this crate either. So, if rust-bitcoin is interested in maintaining this crate, I'll step up and help be a maintainer. However, I'm going to push back on things that I don't think make sense. And maybe you don't like people having opinions other then yours, however I think good maintainers should push back and not just be "yes men". Lastly, I'll say that this API txt thing has been opposed by other maintainers (Kix) and contributors. I'm pretty sure DPW was fairly critical of some policies this project has around tooling when he said "go ahead and fight whatever unproductive tooling wars you want but I'm not following anymore" (paraphrasing).
Given that there seems to be not much interest in maintainers reviewing and helping out, I'm pretty unmotivated to continue to pile time into this. I also don't want to waste your time either if these changes are just not important. So, I'm willing to work on it still if it's useful, although I'm also fine to close this and/or let someone else pick it up. |
|
All fair points. It is true that I feel very little urgency to get anything into Though I don't think it's fair to say that I don't care about the crate, or about this PR in particular, just because I didn't take the time to fix the CI failure. I offered an idea of what might be causing it (which was wrong, but had it been right it might've been nonobvious) and moved on. But ultimately it's the PR author's responsibility, in almost all cases, to get the code to pass CI. I also suspect that much of the reason that Rob, and Tobin, and everyone else, has ignored this PR is because it has a long conversation between you and me that has not ended in an ACK. Anyway FWIW I have put #6525 into my merge queue. Once that passes and merges, and we have a new 0.32.10x release, we can update lockfile here to use that one in the fuzztests, and then this will be good to go. |
|
All good. I would only add that I had all CI tests passing. Your fuzz tests are sort of a hidden obstacle that is non-obvious to anyone submitting a PR. |
a3ae2bc Update API files (Mitchell Bagot) 11c9013 test: V1NetworkMessage sendcmpct should be either 1 or 0 (Mitchell Bagot) 2c1b8a6 Make SendCmpct encode/decode idempotent (Mitchell Bagot) 757815e Replace impl_consensus_encoding call with inline trait impl (Mitchell Bagot) Pull request description: Backport of #6317 From the spec https://bips.dev/152/ > The "high-bandwidth" mode, which nodes may only enable for a few of their peers, is enabled by setting the first boolean to 1 in a sendcmpct message. > The "low-bandwidth" mode is enabled by setting the first boolean to 0 in a sendcmpct message It seems like the spec says that anything besides 1 or 0 is actually an error, though.. Original work by: - yancy \<github@yancy.lol> - Abeeujah \<abeeujah@gmail.com> ACKs for top commit: apoelstra: ACK a3ae2bc; successfully ran local tests Tree-SHA512: 3690ce8d83a44fe96f32fa78d913c49580ffdd80ca145d478ea8972f699055d22e794ef177f68a26ff416fe9c984d6cca94521e773e239692f5cc2c5a3f851f4
On the one hand, yes. On the other hand, we run them on Github in a daily cronjob, so the breakage would've been apparent shortly after merge. Not that this helps you any, as a PR author. |
|
FTR I did not read the whole conversation here. Please excuse me. |
4a50bd1 Update API files (Mitchell Bagot) 8f4aa00 test: V1NetworkMessage sendcmpct should be either 1 or 0 (Mitchell Bagot) 5f0a1cd Make SendCmpct encode/decode idempotent (Mitchell Bagot) dd2e1f2 Replace impl_consensus_encoding call with inline trait impl (Mitchell Bagot) Pull request description: Backport of #6317 From the spec https://bips.dev/152/ > The "high-bandwidth" mode, which nodes may only enable for a few of their peers, is enabled by setting the first boolean to 1 in a sendcmpct message. > The "low-bandwidth" mode is enabled by setting the first boolean to 0 in a sendcmpct message It seems like the spec says that anything besides 1 or 0 is actually an error, though.. Original work by: - yancy \<github@yancy.lol> - Abeeujah \<abeeujah@gmail.com> ACKs for top commit: apoelstra: ACK 4a50bd1; successfully ran local tests tcharding: ACK 4a50bd1 Tree-SHA512: 41be06d3184264084c6f5fdf47a71ee53d4ed5745624b61cd5873c15c92c90698933174d5cc49672ed994e11117355f0389fef49a5fb4b1e0a90df839060967c
|
@yancyribbens are you willing to tack a commit onto here which updates the version of |
|
Actually I can just do it. |
|
Ah, no, I would need to rebase on master since #6416 changed |
Normalizing the mode bit makes serialization/deserealiztion _not_ idempotent. That's due to the checksum that's created before normalization which if serialized again, no longer has the same checksum. This cases a failure to serialize the same `SendCmpct` which was received if the mode bit is anything other then 0 or 1. Furthermore, the spec https://bips.dev/152/ defines only 0 (low-bandwidth mode) or 1 (high-bandwidth mode) so anything other than 0 or 1 is unspecified and should result in an error. As quoted from spec https://bips.dev/152/: The first integer SHALL be interpreted as a boolean (and MUST have a value of either 1 or 0)
Add a test that if the mode bit of the sendcmpct should fail if not 1 or 0.
8a77591 to
e99b8e4
Compare
82b5e6e to
d75c854
Compare
Done. looks like the fuzz tests are passing now 🎉 |
variation of #6297
From the spec https://bips.dev/152/
It seems like the spec says that anything besides 1 or 0 is actually an error, though..