Skip to content

RPC: Take scaling into account for ui amount #4663

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 29, 2025
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
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions account-decoder/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ pub use solana_account_decoder_client_types::{
UiAccount, UiAccountData, UiAccountEncoding, UiDataSliceConfig,
};
use {
crate::parse_account_data::{parse_account_data_v2, AccountAdditionalDataV2},
crate::parse_account_data::{parse_account_data_v3, AccountAdditionalDataV3},
base64::{prelude::BASE64_STANDARD, Engine},
solana_account::ReadableAccount,
solana_fee_calculator::FeeCalculator,
Expand Down Expand Up @@ -49,7 +49,7 @@ pub fn encode_ui_account<T: ReadableAccount>(
pubkey: &Pubkey,
account: &T,
encoding: UiAccountEncoding,
additional_data: Option<AccountAdditionalDataV2>,
additional_data: Option<AccountAdditionalDataV3>,
data_slice_config: Option<UiDataSliceConfig>,
) -> UiAccount {
let space = account.data().len();
Expand Down Expand Up @@ -81,7 +81,7 @@ pub fn encode_ui_account<T: ReadableAccount>(
}
UiAccountEncoding::JsonParsed => {
if let Ok(parsed_data) =
parse_account_data_v2(pubkey, account.owner(), account.data(), additional_data)
parse_account_data_v3(pubkey, account.owner(), account.data(), additional_data)
{
UiAccountData::Json(parsed_data)
} else {
Expand Down
76 changes: 65 additions & 11 deletions account-decoder/src/parse_account_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use {
parse_address_lookup_table::parse_address_lookup_table,
parse_bpf_loader::parse_bpf_upgradeable_loader, parse_config::parse_config,
parse_nonce::parse_nonce, parse_stake::parse_stake, parse_sysvar::parse_sysvar,
parse_token::parse_token_v2, parse_vote::parse_vote,
parse_token::parse_token_v3, parse_vote::parse_vote,
},
inflector::Inflector,
solana_clock::UnixTimestamp,
Expand All @@ -13,7 +13,9 @@ use {
solana_sdk_ids::{
address_lookup_table, bpf_loader_upgradeable, config, stake, system_program, sysvar, vote,
},
spl_token_2022::extension::interest_bearing_mint::InterestBearingConfig,
spl_token_2022::extension::{
interest_bearing_mint::InterestBearingConfig, scaled_ui_amount::ScaledUiAmountConfig,
},
std::collections::HashMap,
thiserror::Error,
};
Expand Down Expand Up @@ -79,17 +81,32 @@ pub enum ParsableAccount {
Vote,
}

#[deprecated(since = "2.0.0", note = "Use `AccountAdditionalDataV2` instead")]
#[deprecated(since = "2.0.0", note = "Use `AccountAdditionalDataV3` instead")]
#[derive(Clone, Copy, Default)]
pub struct AccountAdditionalData {
pub spl_token_decimals: Option<u8>,
}

#[deprecated(since = "2.2.0", note = "Use `AccountAdditionalDataV3` instead")]
#[derive(Clone, Copy, Default)]
pub struct AccountAdditionalDataV2 {
pub spl_token_additional_data: Option<SplTokenAdditionalData>,
}

#[derive(Clone, Copy, Default)]
pub struct AccountAdditionalDataV3 {
pub spl_token_additional_data: Option<SplTokenAdditionalDataV2>,
}

#[allow(deprecated)]
impl From<AccountAdditionalDataV2> for AccountAdditionalDataV3 {
fn from(v: AccountAdditionalDataV2) -> Self {
Self {
spl_token_additional_data: v.spl_token_additional_data.map(Into::into),
}
}
}

#[derive(Clone, Copy, Default)]
pub struct SplTokenAdditionalData {
pub decimals: u8,
Expand All @@ -105,31 +122,68 @@ impl SplTokenAdditionalData {
}
}

#[deprecated(since = "2.0.0", note = "Use `parse_account_data_v2` instead")]
#[derive(Clone, Copy, Default)]
pub struct SplTokenAdditionalDataV2 {
pub decimals: u8,
pub interest_bearing_config: Option<(InterestBearingConfig, UnixTimestamp)>,
pub scaled_ui_amount_config: Option<(ScaledUiAmountConfig, UnixTimestamp)>,
}

impl From<SplTokenAdditionalData> for SplTokenAdditionalDataV2 {
fn from(v: SplTokenAdditionalData) -> Self {
Self {
decimals: v.decimals,
interest_bearing_config: v.interest_bearing_config,
scaled_ui_amount_config: None,
}
}
}

impl SplTokenAdditionalDataV2 {
pub fn with_decimals(decimals: u8) -> Self {
Self {
decimals,
..Default::default()
}
}
}

#[deprecated(since = "2.0.0", note = "Use `parse_account_data_v3` instead")]
#[allow(deprecated)]
pub fn parse_account_data(
pubkey: &Pubkey,
program_id: &Pubkey,
data: &[u8],
additional_data: Option<AccountAdditionalData>,
) -> Result<ParsedAccount, ParseAccountError> {
parse_account_data_v2(
parse_account_data_v3(
pubkey,
program_id,
data,
additional_data.map(|d| AccountAdditionalDataV2 {
additional_data.map(|d| AccountAdditionalDataV3 {
spl_token_additional_data: d
.spl_token_decimals
.map(SplTokenAdditionalData::with_decimals),
.map(SplTokenAdditionalDataV2::with_decimals),
}),
)
}

#[deprecated(since = "2.2.0", note = "Use `parse_account_data_v3` instead")]
#[allow(deprecated)]
pub fn parse_account_data_v2(
pubkey: &Pubkey,
program_id: &Pubkey,
data: &[u8],
additional_data: Option<AccountAdditionalDataV2>,
) -> Result<ParsedAccount, ParseAccountError> {
parse_account_data_v3(pubkey, program_id, data, additional_data.map(Into::into))
}

pub fn parse_account_data_v3(
pubkey: &Pubkey,
program_id: &Pubkey,
data: &[u8],
additional_data: Option<AccountAdditionalDataV3>,
) -> Result<ParsedAccount, ParseAccountError> {
let program_name = PARSABLE_PROGRAM_IDS
.get(program_id)
Expand All @@ -145,7 +199,7 @@ pub fn parse_account_data_v2(
ParsableAccount::Config => serde_json::to_value(parse_config(data, pubkey)?)?,
ParsableAccount::Nonce => serde_json::to_value(parse_nonce(data)?)?,
ParsableAccount::SplToken | ParsableAccount::SplToken2022 => serde_json::to_value(
parse_token_v2(data, additional_data.spl_token_additional_data.as_ref())?,
parse_token_v3(data, additional_data.spl_token_additional_data.as_ref())?,
)?,
ParsableAccount::Stake => serde_json::to_value(parse_stake(data)?)?,
ParsableAccount::Sysvar => serde_json::to_value(parse_sysvar(data, pubkey)?)?,
Expand Down Expand Up @@ -177,13 +231,13 @@ mod test {
let account_pubkey = solana_pubkey::new_rand();
let other_program = solana_pubkey::new_rand();
let data = vec![0; 4];
assert!(parse_account_data_v2(&account_pubkey, &other_program, &data, None).is_err());
assert!(parse_account_data_v3(&account_pubkey, &other_program, &data, None).is_err());

let vote_state = VoteState::default();
let mut vote_account_data: Vec<u8> = vec![0; VoteState::size_of()];
let versioned = VoteStateVersions::new_current(vote_state);
VoteState::serialize(&versioned, &mut vote_account_data).unwrap();
let parsed = parse_account_data_v2(
let parsed = parse_account_data_v3(
&account_pubkey,
&vote_program_id(),
&vote_account_data,
Expand All @@ -195,7 +249,7 @@ mod test {

let nonce_data = Versions::new(State::Initialized(Data::default()));
let nonce_account_data = bincode::serialize(&nonce_data).unwrap();
let parsed = parse_account_data_v2(
let parsed = parse_account_data_v3(
&account_pubkey,
&system_program::id(),
&nonce_account_data,
Expand Down
Loading
Loading