diff --git a/runtime/src/bank.rs b/runtime/src/bank.rs index 6e6b4b94c..ba8cf5886 100644 --- a/runtime/src/bank.rs +++ b/runtime/src/bank.rs @@ -107,6 +107,21 @@ pub struct BankRc { pub(crate) slot: Slot, } +#[cfg(RUSTC_WITH_SPECIALIZATION)] +use solana_sdk::abi_example::AbiExample; +#[cfg(RUSTC_WITH_SPECIALIZATION)] +impl AbiExample for BankRc { + fn example() -> Self { + BankRc { + // Set parent to None to cut the recursion into another Bank + parent: RwLock::new(None), + // AbiExample for Accounts is specially implemented to contain a storage example + accounts: AbiExample::example(), + slot: AbiExample::example(), + } + } +} + impl BankRc { pub(crate) fn new(accounts: Accounts, slot: Slot) -> Self { Self { @@ -265,7 +280,9 @@ pub(crate) struct BankFieldsToSerialize<'a> { } /// Manager for the state of all accounts and programs after processing its entries. -#[derive(Default)] +/// AbiExample is needed even without Serialize/Deserialize; actual (de-)serializeaion +/// are implemented elsewhere for versioning +#[derive(Default, AbiExample)] pub struct Bank { /// References to accounts, parent and signature status pub rc: BankRc, diff --git a/runtime/src/serde_snapshot/tests.rs b/runtime/src/serde_snapshot/tests.rs index 32d677148..cbad14915 100644 --- a/runtime/src/serde_snapshot/tests.rs +++ b/runtime/src/serde_snapshot/tests.rs @@ -279,28 +279,24 @@ fn test_bank_serialize_older() { #[cfg(all(test, RUSTC_WITH_SPECIALIZATION))] mod test_bank_serialize { use super::*; - use solana_sdk::abi_example::AbiExample; // These some what long test harness is required to freeze the ABI of // Bank's serialization due to versioned nature - #[frozen_abi(digest = "9BGkhttaVsELn1zoHMKXLvi3Qty51nY1yz584Fao2Ev9")] - #[derive(Default, Serialize)] + #[frozen_abi(digest = "6MnT4MzuLHe4Uq96YaF3JF2gL1RvprzQHCaV9TaWgYLe")] + #[derive(Serialize, AbiExample)] pub struct BankAbiTestWrapperFuture { #[serde(serialize_with = "wrapper_future")] bank: Bank, } - impl AbiExample for BankAbiTestWrapperFuture { - fn example() -> Self { - Self::default() - } - } - pub fn wrapper_future(bank: &Bank, s: S) -> std::result::Result where S: serde::Serializer, { let snapshot_storages = bank.rc.accounts.accounts_db.get_snapshot_storages(0); + // ensure there is a single snapshot storage example for ABI digesting + assert_eq!(snapshot_storages.len(), 1); + (SerializableBankAndStorage:: { bank, snapshot_storages: &snapshot_storages, @@ -309,24 +305,21 @@ mod test_bank_serialize { .serialize(s) } - #[frozen_abi(digest = "HYmXta1fhiHe6hZLGJriMqKx9N2U8YRJY51AGZmxzM5m")] - #[derive(Default, Serialize)] + #[frozen_abi(digest = "92KVEUQ8PwKe5DgZ6AyDQGAi9pvi7kfHdMBE4hcs5EQ4")] + #[derive(Serialize, AbiExample)] pub struct BankAbiTestWrapperLegacy { #[serde(serialize_with = "wrapper_legacy")] bank: Bank, } - impl AbiExample for BankAbiTestWrapperLegacy { - fn example() -> Self { - Self::default() - } - } - pub fn wrapper_legacy(bank: &Bank, s: S) -> std::result::Result where S: serde::Serializer, { let snapshot_storages = bank.rc.accounts.accounts_db.get_snapshot_storages(0); + // ensure there is a single snapshot storage example for ABI digesting + assert_eq!(snapshot_storages.len(), 1); + (SerializableBankAndStorage:: { bank, snapshot_storages: &snapshot_storages, diff --git a/sdk/src/abi_digester.rs b/sdk/src/abi_digester.rs index 2efb11b26..f228a8d35 100644 --- a/sdk/src/abi_digester.rs +++ b/sdk/src/abi_digester.rs @@ -340,7 +340,12 @@ impl Serializer for AbiDigester { } fn serialize_seq(mut self, len: Option) -> DigestResult { - self.update_with_string(format!("seq (elements = {})", len.unwrap())); + let len = len.unwrap(); + assert_eq!( + len, 1, + "Exactly 1 seq element is needed to generate the ABI digest precisely" + ); + self.update_with_string(format!("seq (elements = {})", len)); Ok(self.create_child()) } @@ -367,7 +372,12 @@ impl Serializer for AbiDigester { } fn serialize_map(mut self, len: Option) -> DigestResult { - self.update_with_string(format!("map (entries = {})", len.unwrap())); + let len = len.unwrap(); + assert_eq!( + len, 1, + "Exactly 1 map entry is needed to generate the ABI digest precisely" + ); + self.update_with_string(format!("map (entries = {})", len)); Ok(self.create_child()) }