AccountSharedData::serialize (#23685)

This commit is contained in:
Jeff Washington (jwash)
2022-03-17 09:29:49 -05:00
committed by GitHub
parent 66b1f55351
commit bb9f9c8dd5
5 changed files with 76 additions and 1 deletions

1
Cargo.lock generated
View File

@ -4856,6 +4856,7 @@ dependencies = [
"bv", "bv",
"generic-array 0.14.5", "generic-array 0.14.5",
"im", "im",
"lazy_static",
"log", "log",
"memmap2 0.5.3", "memmap2 0.5.3",
"rustc_version 0.4.0", "rustc_version 0.4.0",

View File

@ -12,6 +12,7 @@ edition = "2021"
[dependencies] [dependencies]
bs58 = "0.4.0" bs58 = "0.4.0"
bv = { version = "0.11.1", features = ["serde"] } bv = { version = "0.11.1", features = ["serde"] }
lazy_static = "1.4.0"
log = "0.4.14" log = "0.4.14"
serde = "1.0.136" serde = "1.0.136"
serde_derive = "1.0.103" serde_derive = "1.0.103"

View File

@ -1,5 +1,6 @@
use { use {
crate::abi_digester::{AbiDigester, DigestError, DigestResult}, crate::abi_digester::{AbiDigester, DigestError, DigestResult},
lazy_static::lazy_static,
log::*, log::*,
serde::Serialize, serde::Serialize,
std::any::type_name, std::any::type_name,
@ -402,6 +403,18 @@ impl<T: AbiExample> AbiExample for Vec<T> {
} }
} }
lazy_static! {
/// we need &Vec<u8>, so we need something with a static lifetime
static ref VEC_U8: Vec<u8> = vec![u8::default()];
}
impl AbiExample for &Vec<u8> {
fn example() -> Self {
info!("AbiExample for (&Vec<T>): {}", type_name::<Self>());
&*VEC_U8
}
}
impl<T: AbiExample> AbiExample for VecDeque<T> { impl<T: AbiExample> AbiExample for VecDeque<T> {
fn example() -> Self { fn example() -> Self {
info!("AbiExample for (Vec<T>): {}", type_name::<Self>()); info!("AbiExample for (Vec<T>): {}", type_name::<Self>());

View File

@ -3365,6 +3365,7 @@ dependencies = [
"bv", "bv",
"generic-array 0.14.5", "generic-array 0.14.5",
"im", "im",
"lazy_static",
"log", "log",
"memmap2 0.5.3", "memmap2 0.5.3",
"rustc_version 0.4.0", "rustc_version 0.4.0",

View File

@ -4,6 +4,7 @@ use {
lamports::LamportsError, lamports::LamportsError,
pubkey::Pubkey, pubkey::Pubkey,
}, },
serde::ser::{Serialize, Serializer},
solana_program::{account_info::AccountInfo, debug_account_data::*, sysvar::Sysvar}, solana_program::{account_info::AccountInfo, debug_account_data::*, sysvar::Sysvar},
std::{ std::{
cell::{Ref, RefCell}, cell::{Ref, RefCell},
@ -16,7 +17,7 @@ use {
/// An Account with data that is stored on chain /// An Account with data that is stored on chain
#[repr(C)] #[repr(C)]
#[frozen_abi(digest = "HawRVHh7t4d3H3bitWHFt25WhhoDmbJMCfWdESQQoYEy")] #[frozen_abi(digest = "HawRVHh7t4d3H3bitWHFt25WhhoDmbJMCfWdESQQoYEy")]
#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Default, AbiExample)] #[derive(Deserialize, PartialEq, Eq, Clone, Default, AbiExample)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct Account { pub struct Account {
/// lamports in the account /// lamports in the account
@ -32,6 +33,64 @@ pub struct Account {
pub rent_epoch: Epoch, 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<u8>,
// can't be &pubkey because abi example doesn't support it
owner: Pubkey,
executable: bool,
rent_epoch: Epoch,
}
pub fn serialize_account<S>(
account: &(impl ReadableAccount + Serialize),
data: &Vec<u8>,
serializer: S,
) -> Result<S::Ok, S::Error>
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<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
crate::account::account_serialize::serialize_account(self, &self.data, serializer)
}
}
impl Serialize for AccountSharedData {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
crate::account::account_serialize::serialize_account(self, &self.data, serializer)
}
}
/// An Account with data that is stored on chain /// An Account with data that is stored on chain
/// This will be the in-memory representation of the 'Account' struct data. /// This will be the in-memory representation of the 'Account' struct data.
/// The existing 'Account' structure cannot easily change due to downstream projects. /// The existing 'Account' structure cannot easily change due to downstream projects.