Capabilities now deserialize safely (#1946)

* deserialize capabilities dropping unknown flag bits

* add tests for capabilities deserialization

* rustfmt

* FULL_NODE needs to be handled safely for legacy nodes
This commit is contained in:
Antioch Peverell 2018-11-07 11:15:37 +00:00 committed by GitHub
parent e25a3b9d72
commit ab30f714fc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 43 additions and 6 deletions

View file

@ -362,7 +362,7 @@ impl Writeable for Hand {
impl Readable for Hand {
fn read(reader: &mut Reader) -> Result<Hand, ser::Error> {
let (version, capab, nonce) = ser_multiread!(reader, read_u32, read_u32, read_u64);
let capabilities = Capabilities::from_bits(capab).ok_or(ser::Error::CorruptedData)?;
let capabilities = Capabilities::from_bits_truncate(capab);
let total_diff = Difficulty::read(reader)?;
let sender_addr = SockAddr::read(reader)?;
let receiver_addr = SockAddr::read(reader)?;
@ -415,7 +415,7 @@ impl Writeable for Shake {
impl Readable for Shake {
fn read(reader: &mut Reader) -> Result<Shake, ser::Error> {
let (version, capab) = ser_multiread!(reader, read_u32, read_u32);
let capabilities = Capabilities::from_bits(capab).ok_or(ser::Error::CorruptedData)?;
let capabilities = Capabilities::from_bits_truncate(capab);
let total_diff = Difficulty::read(reader)?;
let ua = reader.read_vec()?;
let user_agent = String::from_utf8(ua).map_err(|_| ser::Error::CorruptedData)?;
@ -445,7 +445,7 @@ impl Writeable for GetPeerAddrs {
impl Readable for GetPeerAddrs {
fn read(reader: &mut Reader) -> Result<GetPeerAddrs, ser::Error> {
let capab = reader.read_u32()?;
let capabilities = Capabilities::from_bits(capab).ok_or(ser::Error::CorruptedData)?;
let capabilities = Capabilities::from_bits_truncate(capab);
Ok(GetPeerAddrs { capabilities })
}
}

View file

@ -91,7 +91,7 @@ impl Readable for PeerData {
lc.unwrap()
};
let user_agent = String::from_utf8(ua).map_err(|_| ser::Error::CorruptedData)?;
let capabilities = Capabilities::from_bits(capab).ok_or(ser::Error::CorruptedData)?;
let capabilities = Capabilities::from_bits_truncate(capab);
let ban_reason = ReasonForBan::from_i32(br).ok_or(ser::Error::CorruptedData)?;
match State::from_u8(fl) {

View file

@ -216,8 +216,11 @@ bitflags! {
/// but we do not advertise this to other nodes.
const FULL_NODE = Capabilities::HEADER_HIST.bits
| Capabilities::TXHASHSET_HIST.bits
| Capabilities::PEER_LIST.bits
| Capabilities::TX_KERNEL_HASH.bits;
| Capabilities::PEER_LIST.bits;
// TODO - we cannot include TX_KERNEL_HASH in FULL_NODE right now
// as legacy nodes do not recognise these Capabilities safely.
// | Capabilities::TX_KERNEL_HASH.bits;
}
}

View file

@ -42,3 +42,37 @@ fn test_reason_for_ban_enum() {
fn test_type_enum() {
assert_eq!(p2p::msg::Type::from_i32(0), Some(p2p::msg::Type::Error));
}
#[test]
fn test_capabilities() {
assert_eq!(
p2p::types::Capabilities::from_bits_truncate(0b00000000 as u32),
p2p::types::Capabilities::UNKNOWN
);
assert_eq!(
p2p::types::Capabilities::from_bits_truncate(0b10000000 as u32),
p2p::types::Capabilities::UNKNOWN
);
assert_eq!(
p2p::types::Capabilities::from_bits_truncate(0b0111 as u32),
p2p::types::Capabilities::FULL_NODE
);
assert_eq!(
p2p::types::Capabilities::from_bits_truncate(0b00000111 as u32),
p2p::types::Capabilities::FULL_NODE
);
assert_eq!(
p2p::types::Capabilities::from_bits_truncate(0b11110111 as u32),
p2p::types::Capabilities::FULL_NODE
);
assert_eq!(
p2p::types::Capabilities::from_bits_truncate(0b00100111 as u32),
p2p::types::Capabilities::FULL_NODE
);
assert_eq!(
p2p::types::Capabilities::from_bits_truncate(0b00101111 as u32),
p2p::types::Capabilities::FULL_NODE | p2p::types::Capabilities::TX_KERNEL_HASH
);
}