diff --git a/Cargo.lock b/Cargo.lock index 4cc72f6cf3..025fe7e749 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4856,6 +4856,7 @@ dependencies = [ "bv", "generic-array 0.14.5", "im", + "lazy_static", "log", "memmap2 0.5.3", "rustc_version 0.4.0", diff --git a/frozen-abi/Cargo.toml b/frozen-abi/Cargo.toml index c72b811f7e..d38540f33e 100644 --- a/frozen-abi/Cargo.toml +++ b/frozen-abi/Cargo.toml @@ -12,6 +12,7 @@ edition = "2021" [dependencies] bs58 = "0.4.0" bv = { version = "0.11.1", features = ["serde"] } +lazy_static = "1.4.0" log = "0.4.14" serde = "1.0.136" serde_derive = "1.0.103" diff --git a/frozen-abi/src/abi_example.rs b/frozen-abi/src/abi_example.rs index b6a7f2d691..ac4971d1ee 100644 --- a/frozen-abi/src/abi_example.rs +++ b/frozen-abi/src/abi_example.rs @@ -1,5 +1,6 @@ use { crate::abi_digester::{AbiDigester, DigestError, DigestResult}, + lazy_static::lazy_static, log::*, serde::Serialize, std::any::type_name, @@ -402,6 +403,18 @@ impl AbiExample for Vec { } } +lazy_static! { + /// we need &Vec, so we need something with a static lifetime + static ref VEC_U8: Vec = vec![u8::default()]; +} + +impl AbiExample for &Vec { + fn example() -> Self { + info!("AbiExample for (&Vec): {}", type_name::()); + &*VEC_U8 + } +} + impl AbiExample for VecDeque { fn example() -> Self { info!("AbiExample for (Vec): {}", type_name::()); diff --git a/programs/bpf/Cargo.lock b/programs/bpf/Cargo.lock index 9f9e649b2b..3498b2710a 100644 --- a/programs/bpf/Cargo.lock +++ b/programs/bpf/Cargo.lock @@ -3365,6 +3365,7 @@ dependencies = [ "bv", "generic-array 0.14.5", "im", + "lazy_static", "log", "memmap2 0.5.3", "rustc_version 0.4.0", diff --git a/sdk/src/account.rs b/sdk/src/account.rs index d0cae18c24..310d4078f7 100644 --- a/sdk/src/account.rs +++ b/sdk/src/account.rs @@ -4,6 +4,7 @@ use { lamports::LamportsError, pubkey::Pubkey, }, + serde::ser::{Serialize, Serializer}, solana_program::{account_info::AccountInfo, debug_account_data::*, sysvar::Sysvar}, std::{ cell::{Ref, RefCell}, @@ -16,7 +17,7 @@ use { /// An Account with data that is stored on chain #[repr(C)] #[frozen_abi(digest = "HawRVHh7t4d3H3bitWHFt25WhhoDmbJMCfWdESQQoYEy")] -#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Default, AbiExample)] +#[derive(Deserialize, PartialEq, Eq, Clone, Default, AbiExample)] #[serde(rename_all = "camelCase")] pub struct Account { /// lamports in the account @@ -32,6 +33,64 @@ pub struct Account { pub rent_epoch: Epoch, } +// mod because we need 'Account' below to have the name 'Account' to match expected serialization +mod account_serialize { + use { + crate::{account::ReadableAccount, clock::Epoch, pubkey::Pubkey}, + serde::{ser::Serializer, Serialize}, + }; + #[repr(C)] + #[frozen_abi(digest = "HawRVHh7t4d3H3bitWHFt25WhhoDmbJMCfWdESQQoYEy")] + #[derive(Serialize, AbiExample)] + #[serde(rename_all = "camelCase")] + struct Account<'a> { + lamports: u64, + #[serde(with = "serde_bytes")] + // a ref so we don't have to make a copy just to serialize this + data: &'a Vec, + // can't be &pubkey because abi example doesn't support it + owner: Pubkey, + executable: bool, + rent_epoch: Epoch, + } + + pub fn serialize_account( + account: &(impl ReadableAccount + Serialize), + data: &Vec, + serializer: S, + ) -> Result + where + S: Serializer, + { + let temp = Account { + lamports: account.lamports(), + data, + owner: *account.owner(), + executable: account.executable(), + rent_epoch: account.rent_epoch(), + }; + temp.serialize(serializer) + } +} + +impl Serialize for Account { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + crate::account::account_serialize::serialize_account(self, &self.data, serializer) + } +} + +impl Serialize for AccountSharedData { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + crate::account::account_serialize::serialize_account(self, &self.data, serializer) + } +} + /// An Account with data that is stored on chain /// This will be the in-memory representation of the 'Account' struct data. /// The existing 'Account' structure cannot easily change due to downstream projects.