-
Notifications
You must be signed in to change notification settings - Fork 177
Open
Description
while working on the improvements proposed in #2028, we noticed that the round-trip serialization is not lossless: deserializing a message and serializing it again can change the original byte stream.
To demonstrate the issue, you can apply this unit test for the NewExtendedMiningJob message that explicitly checks for byte-for-byte round-trip correctness.
Reproducer
The following test parses a raw byte vector into a NewExtendedMiningJob, serializes it back, and asserts that the output matches the original input exactly:
diff --git a/sv2/subprotocols/mining/src/new_mining_job.rs b/sv2/subprotocols/mining/src/new_mining_job.rs
index 9167be97..bf42800d 100644
--- a/sv2/subprotocols/mining/src/new_mining_job.rs
+++ b/sv2/subprotocols/mining/src/new_mining_job.rs
@@ -152,6 +152,8 @@ impl NewExtendedMiningJob<'_> {
#[cfg(test)]
mod tests {
+ use binary_sv2::GetSize;
+
use super::*;
use crate::tests::from_arbitrary_vec_to_array;
use core::convert::TryFrom;
@@ -217,6 +219,24 @@ mod tests {
&& static_nmj.merkle_root == nmj.merkle_root
}
+ #[test]
+ fn test_lossy_bytes() {
+ let mut bytes = vec![
+ 255, 231, 255, 0, 50, 197, 5, 5, 1, 255, 255, 5, 5, 255, 5, 5, 1, 255, 0, 7, 0, 255,
+ 255, 255, 255, 173, 0, 197, 0, 0,
+ ];
+
+ let msg = NewExtendedMiningJob::from_bytes(&mut bytes).unwrap();
+
+ let mut encoded = vec![0u8; msg.get_size()];
+ msg.to_bytes(&mut encoded).unwrap();
+
+ assert_eq!(
+ bytes, encoded,
+ "Expected a lossless byte round-trip, but encoding changed the input bytes"
+ );
+ }
+
pub mod helpers {
use super::*;
use alloc::borrow::ToOwned;Failure
Running the test:
cargo test test_lossy_bytesresults in the following failure:
running 1 test
test new_mining_job::tests::test_lossy_bytes ... FAILED
failures:
---- new_mining_job::tests::test_lossy_bytes stdout ----
thread 'new_mining_job::tests::test_lossy_bytes' panicked at sv2/subprotocols/mining/src/new_mining_job.rs:234:9:
assertion `left == right` failed: Expected a lossless byte round-trip, but encoding changed the input bytes
left: [255, 231, 255, 0, 50, 197, 5, 5, 1, 255, 255, 5, 5, 255, 5, 5, 1, 255, 0, 7, 0, 255, 255, 255, 255, 173, 0, 197, 0, 0]
right: [255, 231, 255, 0, 50, 197, 5, 5, 1, 255, 255, 5, 5, 255, 5, 5, 1, 1, 0, 7, 0, 255, 255, 255, 255, 173, 0, 197, 0, 0]
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
failures:
new_mining_job::tests::test_lossy_bytes
test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 26 filtered out; finished in 0.00s
error: test failed, to rerun pass `--lib`
Specifically, the byte at index 17 is modified during the round-trip: its value changes from 255 to 1.

Metadata
Metadata
Assignees
Labels
No labels