Stop panicking when Zebra sends a reject without extra data
Also add round-trip unit tests for extra data and no extra data.
This commit is contained in:
parent
15843cfd6e
commit
59aa04c9b9
|
@ -251,7 +251,9 @@ impl Codec {
|
||||||
writer.write_string(&message)?;
|
writer.write_string(&message)?;
|
||||||
writer.write_u8(*ccode as u8)?;
|
writer.write_u8(*ccode as u8)?;
|
||||||
writer.write_string(&reason)?;
|
writer.write_string(&reason)?;
|
||||||
writer.write_all(&data.unwrap())?;
|
if let Some(data) = data {
|
||||||
|
writer.write_all(data)?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Message::Addr(addrs) => addrs.zcash_serialize(&mut writer)?,
|
Message::Addr(addrs) => addrs.zcash_serialize(&mut writer)?,
|
||||||
Message::GetAddr => { /* Empty payload -- no-op */ }
|
Message::GetAddr => { /* Empty payload -- no-op */ }
|
||||||
|
@ -511,7 +513,8 @@ impl Codec {
|
||||||
// data (hash identifying the rejected object) or none (and we model
|
// data (hash identifying the rejected object) or none (and we model
|
||||||
// the Reject message that way), so instead of passing in the
|
// the Reject message that way), so instead of passing in the
|
||||||
// body_len separately and calculating remaining bytes, just try to
|
// body_len separately and calculating remaining bytes, just try to
|
||||||
// read 32 bytes and ignore any failures.
|
// read 32 bytes and ignore any failures. (The caller will log and
|
||||||
|
// ignore any trailing bytes.)
|
||||||
data: reader.read_32_bytes().ok(),
|
data: reader.read_32_bytes().ok(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -720,6 +723,78 @@ mod tests {
|
||||||
assert_eq!(v, v_parsed);
|
assert_eq!(v, v_parsed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn reject_message_no_extra_data_round_trip() {
|
||||||
|
zebra_test::init();
|
||||||
|
|
||||||
|
let rt = Runtime::new().unwrap();
|
||||||
|
|
||||||
|
let v = Message::Reject {
|
||||||
|
message: "experimental".to_string(),
|
||||||
|
ccode: RejectReason::Malformed,
|
||||||
|
reason: "message could not be decoded".to_string(),
|
||||||
|
data: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
use tokio_util::codec::{FramedRead, FramedWrite};
|
||||||
|
let v_bytes = rt.block_on(async {
|
||||||
|
let mut bytes = Vec::new();
|
||||||
|
{
|
||||||
|
let mut fw = FramedWrite::new(&mut bytes, Codec::builder().finish());
|
||||||
|
fw.send(v.clone())
|
||||||
|
.await
|
||||||
|
.expect("message should be serialized");
|
||||||
|
}
|
||||||
|
bytes
|
||||||
|
});
|
||||||
|
|
||||||
|
let v_parsed = rt.block_on(async {
|
||||||
|
let mut fr = FramedRead::new(Cursor::new(&v_bytes), Codec::builder().finish());
|
||||||
|
fr.next()
|
||||||
|
.await
|
||||||
|
.expect("a next message should be available")
|
||||||
|
.expect("that message should deserialize")
|
||||||
|
});
|
||||||
|
|
||||||
|
assert_eq!(v, v_parsed);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn reject_message_extra_data_round_trip() {
|
||||||
|
zebra_test::init();
|
||||||
|
|
||||||
|
let rt = Runtime::new().unwrap();
|
||||||
|
|
||||||
|
let v = Message::Reject {
|
||||||
|
message: "block".to_string(),
|
||||||
|
ccode: RejectReason::Invalid,
|
||||||
|
reason: "invalid block difficulty".to_string(),
|
||||||
|
data: Some([0xff; 32]),
|
||||||
|
};
|
||||||
|
|
||||||
|
use tokio_util::codec::{FramedRead, FramedWrite};
|
||||||
|
let v_bytes = rt.block_on(async {
|
||||||
|
let mut bytes = Vec::new();
|
||||||
|
{
|
||||||
|
let mut fw = FramedWrite::new(&mut bytes, Codec::builder().finish());
|
||||||
|
fw.send(v.clone())
|
||||||
|
.await
|
||||||
|
.expect("message should be serialized");
|
||||||
|
}
|
||||||
|
bytes
|
||||||
|
});
|
||||||
|
|
||||||
|
let v_parsed = rt.block_on(async {
|
||||||
|
let mut fr = FramedRead::new(Cursor::new(&v_bytes), Codec::builder().finish());
|
||||||
|
fr.next()
|
||||||
|
.await
|
||||||
|
.expect("a next message should be available")
|
||||||
|
.expect("that message should deserialize")
|
||||||
|
});
|
||||||
|
|
||||||
|
assert_eq!(v, v_parsed);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn filterload_message_too_large_round_trip() {
|
fn filterload_message_too_large_round_trip() {
|
||||||
zebra_test::init();
|
zebra_test::init();
|
||||||
|
|
Loading…
Reference in New Issue