Skip to content
This repository has been archived by the owner on Jan 13, 2025. It is now read-only.

Ensure to digest non-empty snapshot_storages and add asserts #11021

Merged
merged 2 commits into from
Jul 13, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 18 additions & 1 deletion runtime/src/bank.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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,
Expand Down
27 changes: 10 additions & 17 deletions runtime/src/serde_snapshot/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<S>(bank: &Bank, s: S) -> std::result::Result<S::Ok, S::Error>
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::<future::Context> {
bank,
snapshot_storages: &snapshot_storages,
Expand All @@ -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<S>(bank: &Bank, s: S) -> std::result::Result<S::Ok, S::Error>
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::<legacy::Context> {
bank,
snapshot_storages: &snapshot_storages,
Expand Down
14 changes: 12 additions & 2 deletions sdk/src/abi_digester.rs
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,12 @@ impl Serializer for AbiDigester {
}

fn serialize_seq(mut self, len: Option<usize>) -> 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())
}

Expand All @@ -367,7 +372,12 @@ impl Serializer for AbiDigester {
}

fn serialize_map(mut self, len: Option<usize>) -> 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())
}

Expand Down