diff --git a/runtime/src/serde_snapshot.rs b/runtime/src/serde_snapshot.rs index 28964394c21785..ffc35fca4bac74 100644 --- a/runtime/src/serde_snapshot.rs +++ b/runtime/src/serde_snapshot.rs @@ -57,10 +57,12 @@ use { thread::Builder, }, storage::SerializableStorage, + types::SerdeAccountsLtHash, }; mod storage; mod tests; +mod types; mod utils; pub(crate) use { @@ -419,6 +421,10 @@ where .map(|(epoch, versioned_epoch_stakes)| (epoch, versioned_epoch_stakes.into())), ); + // This field is only deserialized (and ignored) in this version. + let _accounts_lt_hash: Option = + ignore_eof_error(deserialize_from(&mut stream))?; + Ok((bank_fields, accounts_db_fields)) } diff --git a/runtime/src/serde_snapshot/types.rs b/runtime/src/serde_snapshot/types.rs new file mode 100644 index 00000000000000..f80416eb4e72e2 --- /dev/null +++ b/runtime/src/serde_snapshot/types.rs @@ -0,0 +1,48 @@ +use { + serde::{de, Deserialize, Deserializer}, + std::{fmt, marker::PhantomData}, +}; + +/// Snapshot serde-safe AccountsLtHash +#[cfg_attr(feature = "frozen-abi", derive(AbiExample))] +#[derive(Debug)] +pub struct SerdeAccountsLtHash( + // serde only has array support up to 32 elements; anything larger needs to be handled manually + // see https://github.com/serde-rs/serde/issues/1937 for more information + #[allow(dead_code)] pub [u16; 1024], +); + +impl<'de> Deserialize<'de> for SerdeAccountsLtHash { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct ArrayVisitor { + element: PhantomData, + } + impl<'de> de::Visitor<'de> for ArrayVisitor { + type Value = [u16; 1024]; + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str(concat!("a u16 array of length 1024")) + } + fn visit_seq(self, mut seq: A) -> Result + where + A: de::SeqAccess<'de>, + { + let mut arr = [0u16; 1024]; + for (i, elem) in arr.iter_mut().enumerate() { + *elem = seq + .next_element()? + .ok_or_else(|| de::Error::invalid_length(i, &self))?; + } + Ok(arr) + } + } + + let visitor = ArrayVisitor { + element: PhantomData, + }; + let array = deserializer.deserialize_tuple(1024, visitor)?; + Ok(Self(array)) + } +}