Fix versioned message json deserialization (#34808)
This commit is contained in:
parent
6dbcdc063f
commit
747df9c105
|
@ -8,7 +8,7 @@ use {
|
||||||
short_vec,
|
short_vec,
|
||||||
},
|
},
|
||||||
serde::{
|
serde::{
|
||||||
de::{self, Deserializer, SeqAccess, Visitor},
|
de::{self, Deserializer, SeqAccess, Unexpected, Visitor},
|
||||||
ser::{SerializeTuple, Serializer},
|
ser::{SerializeTuple, Serializer},
|
||||||
Deserialize, Serialize,
|
Deserialize, Serialize,
|
||||||
},
|
},
|
||||||
|
@ -198,7 +198,16 @@ impl<'de> Deserialize<'de> for MessagePrefix {
|
||||||
formatter.write_str("message prefix byte")
|
formatter.write_str("message prefix byte")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_u8<E>(self, byte: u8) -> Result<MessagePrefix, E> {
|
// Serde's integer visitors bubble up to u64 so check the prefix
|
||||||
|
// with this function instead of visit_u8. This approach is
|
||||||
|
// necessary because serde_json directly calls visit_u64 for
|
||||||
|
// unsigned integers.
|
||||||
|
fn visit_u64<E: de::Error>(self, value: u64) -> Result<MessagePrefix, E> {
|
||||||
|
if value > u8::MAX as u64 {
|
||||||
|
Err(de::Error::invalid_type(Unexpected::Unsigned(value), &self))?;
|
||||||
|
}
|
||||||
|
|
||||||
|
let byte = value as u8;
|
||||||
if byte & MESSAGE_VERSION_PREFIX != 0 {
|
if byte & MESSAGE_VERSION_PREFIX != 0 {
|
||||||
Ok(MessagePrefix::Versioned(byte & !MESSAGE_VERSION_PREFIX))
|
Ok(MessagePrefix::Versioned(byte & !MESSAGE_VERSION_PREFIX))
|
||||||
} else {
|
} else {
|
||||||
|
@ -331,26 +340,32 @@ mod tests {
|
||||||
|
|
||||||
let mut message = LegacyMessage::new(&instructions, Some(&id1));
|
let mut message = LegacyMessage::new(&instructions, Some(&id1));
|
||||||
message.recent_blockhash = Hash::new_unique();
|
message.recent_blockhash = Hash::new_unique();
|
||||||
|
let wrapped_message = VersionedMessage::Legacy(message.clone());
|
||||||
|
|
||||||
let bytes1 = bincode::serialize(&message).unwrap();
|
// bincode
|
||||||
let bytes2 = bincode::serialize(&VersionedMessage::Legacy(message.clone())).unwrap();
|
{
|
||||||
|
let bytes = bincode::serialize(&message).unwrap();
|
||||||
|
assert_eq!(bytes, bincode::serialize(&wrapped_message).unwrap());
|
||||||
|
|
||||||
assert_eq!(bytes1, bytes2);
|
let message_from_bytes: LegacyMessage = bincode::deserialize(&bytes).unwrap();
|
||||||
|
let wrapped_message_from_bytes: VersionedMessage =
|
||||||
|
bincode::deserialize(&bytes).unwrap();
|
||||||
|
|
||||||
let message1: LegacyMessage = bincode::deserialize(&bytes1).unwrap();
|
assert_eq!(message, message_from_bytes);
|
||||||
let message2: VersionedMessage = bincode::deserialize(&bytes2).unwrap();
|
assert_eq!(wrapped_message, wrapped_message_from_bytes);
|
||||||
|
}
|
||||||
|
|
||||||
if let VersionedMessage::Legacy(message2) = message2 {
|
// serde_json
|
||||||
assert_eq!(message, message1);
|
{
|
||||||
assert_eq!(message1, message2);
|
let string = serde_json::to_string(&message).unwrap();
|
||||||
} else {
|
let message_from_string: LegacyMessage = serde_json::from_str(&string).unwrap();
|
||||||
panic!("should deserialize to legacy message");
|
assert_eq!(message, message_from_string);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_versioned_message_serialization() {
|
fn test_versioned_message_serialization() {
|
||||||
let message = v0::Message {
|
let message = VersionedMessage::V0(v0::Message {
|
||||||
header: MessageHeader {
|
header: MessageHeader {
|
||||||
num_required_signatures: 1,
|
num_required_signatures: 1,
|
||||||
num_readonly_signed_accounts: 0,
|
num_readonly_signed_accounts: 0,
|
||||||
|
@ -375,15 +390,14 @@ mod tests {
|
||||||
accounts: vec![0, 2, 3, 4],
|
accounts: vec![0, 2, 3, 4],
|
||||||
data: vec![],
|
data: vec![],
|
||||||
}],
|
}],
|
||||||
};
|
});
|
||||||
|
|
||||||
let bytes = bincode::serialize(&VersionedMessage::V0(message.clone())).unwrap();
|
let bytes = bincode::serialize(&message).unwrap();
|
||||||
let message_from_bytes: VersionedMessage = bincode::deserialize(&bytes).unwrap();
|
let message_from_bytes: VersionedMessage = bincode::deserialize(&bytes).unwrap();
|
||||||
|
assert_eq!(message, message_from_bytes);
|
||||||
|
|
||||||
if let VersionedMessage::V0(message_from_bytes) = message_from_bytes {
|
let string = serde_json::to_string(&message).unwrap();
|
||||||
assert_eq!(message, message_from_bytes);
|
let message_from_string: VersionedMessage = serde_json::from_str(&string).unwrap();
|
||||||
} else {
|
assert_eq!(message, message_from_string);
|
||||||
panic!("should deserialize to versioned message");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue