Skip to content

Commit e0dc5dc

Browse files
authored
rpc: Include interest-bearing configuration for UI amount calculation (solana-labs#1549)
* Plumb new SplTokenAdditionalData everywhere * account-decoder: Calculate ui amount with interest * rpc / ledger: Populate interest bearing information * rpc: Test interest-bearing config * Deprecate `parse_token` for `parse_token_v2` * Deprecate parse_account_data and AccountAdditionalData for v2 * Deprecate token_amount_to_ui_amount -> v2 * Make get_mint_owner_and_additional_data pub(crate) * ledger: Revert changes, always use raw amount
1 parent 31334c4 commit e0dc5dc

File tree

11 files changed

+353
-125
lines changed

11 files changed

+353
-125
lines changed

account-decoder/src/lib.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ pub mod parse_vote;
1818
pub mod validator_info;
1919

2020
use {
21-
crate::parse_account_data::{parse_account_data, AccountAdditionalData, ParsedAccount},
21+
crate::parse_account_data::{parse_account_data_v2, AccountAdditionalDataV2, ParsedAccount},
2222
base64::{prelude::BASE64_STANDARD, Engine},
2323
solana_sdk::{
2424
account::{ReadableAccount, WritableAccount},
@@ -108,7 +108,7 @@ impl UiAccount {
108108
pubkey: &Pubkey,
109109
account: &T,
110110
encoding: UiAccountEncoding,
111-
additional_data: Option<AccountAdditionalData>,
111+
additional_data: Option<AccountAdditionalDataV2>,
112112
data_slice_config: Option<UiDataSliceConfig>,
113113
) -> Self {
114114
let space = account.data().len();
@@ -142,7 +142,7 @@ impl UiAccount {
142142
}
143143
UiAccountEncoding::JsonParsed => {
144144
if let Ok(parsed_data) =
145-
parse_account_data(pubkey, account.owner(), account.data(), additional_data)
145+
parse_account_data_v2(pubkey, account.owner(), account.data(), additional_data)
146146
{
147147
UiAccountData::Json(parsed_data)
148148
} else {

account-decoder/src/parse_account_data.rs

+51-9
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,15 @@ use {
33
parse_address_lookup_table::parse_address_lookup_table,
44
parse_bpf_loader::parse_bpf_upgradeable_loader, parse_config::parse_config,
55
parse_nonce::parse_nonce, parse_stake::parse_stake, parse_sysvar::parse_sysvar,
6-
parse_token::parse_token, parse_vote::parse_vote,
6+
parse_token::parse_token_v2, parse_vote::parse_vote,
77
},
88
inflector::Inflector,
99
serde_json::Value,
1010
solana_sdk::{
11-
address_lookup_table, instruction::InstructionError, pubkey::Pubkey, stake, system_program,
12-
sysvar, vote,
11+
address_lookup_table, clock::UnixTimestamp, instruction::InstructionError, pubkey::Pubkey,
12+
stake, system_program, sysvar, vote,
1313
},
14+
spl_token_2022::extension::interest_bearing_mint::InterestBearingConfig,
1415
std::collections::HashMap,
1516
thiserror::Error,
1617
};
@@ -84,16 +85,57 @@ pub enum ParsableAccount {
8485
Vote,
8586
}
8687

88+
#[deprecated(since = "2.0.0", note = "Use `AccountAdditionalDataV2` instead")]
8789
#[derive(Clone, Copy, Default)]
8890
pub struct AccountAdditionalData {
8991
pub spl_token_decimals: Option<u8>,
9092
}
9193

94+
#[derive(Clone, Copy, Default)]
95+
pub struct AccountAdditionalDataV2 {
96+
pub spl_token_additional_data: Option<SplTokenAdditionalData>,
97+
}
98+
99+
#[derive(Clone, Copy, Default)]
100+
pub struct SplTokenAdditionalData {
101+
pub decimals: u8,
102+
pub interest_bearing_config: Option<(InterestBearingConfig, UnixTimestamp)>,
103+
}
104+
105+
impl SplTokenAdditionalData {
106+
pub fn with_decimals(decimals: u8) -> Self {
107+
Self {
108+
decimals,
109+
..Default::default()
110+
}
111+
}
112+
}
113+
114+
#[deprecated(since = "2.0.0", note = "Use `parse_account_data_v2` instead")]
115+
#[allow(deprecated)]
92116
pub fn parse_account_data(
93117
pubkey: &Pubkey,
94118
program_id: &Pubkey,
95119
data: &[u8],
96120
additional_data: Option<AccountAdditionalData>,
121+
) -> Result<ParsedAccount, ParseAccountError> {
122+
parse_account_data_v2(
123+
pubkey,
124+
program_id,
125+
data,
126+
additional_data.map(|d| AccountAdditionalDataV2 {
127+
spl_token_additional_data: d
128+
.spl_token_decimals
129+
.map(SplTokenAdditionalData::with_decimals),
130+
}),
131+
)
132+
}
133+
134+
pub fn parse_account_data_v2(
135+
pubkey: &Pubkey,
136+
program_id: &Pubkey,
137+
data: &[u8],
138+
additional_data: Option<AccountAdditionalDataV2>,
97139
) -> Result<ParsedAccount, ParseAccountError> {
98140
let program_name = PARSABLE_PROGRAM_IDS
99141
.get(program_id)
@@ -108,9 +150,9 @@ pub fn parse_account_data(
108150
}
109151
ParsableAccount::Config => serde_json::to_value(parse_config(data, pubkey)?)?,
110152
ParsableAccount::Nonce => serde_json::to_value(parse_nonce(data)?)?,
111-
ParsableAccount::SplToken | ParsableAccount::SplToken2022 => {
112-
serde_json::to_value(parse_token(data, additional_data.spl_token_decimals)?)?
113-
}
153+
ParsableAccount::SplToken | ParsableAccount::SplToken2022 => serde_json::to_value(
154+
parse_token_v2(data, additional_data.spl_token_additional_data.as_ref())?,
155+
)?,
114156
ParsableAccount::Stake => serde_json::to_value(parse_stake(data)?)?,
115157
ParsableAccount::Sysvar => serde_json::to_value(parse_sysvar(data, pubkey)?)?,
116158
ParsableAccount::Vote => serde_json::to_value(parse_vote(data)?)?,
@@ -143,13 +185,13 @@ mod test {
143185
let account_pubkey = solana_sdk::pubkey::new_rand();
144186
let other_program = solana_sdk::pubkey::new_rand();
145187
let data = vec![0; 4];
146-
assert!(parse_account_data(&account_pubkey, &other_program, &data, None).is_err());
188+
assert!(parse_account_data_v2(&account_pubkey, &other_program, &data, None).is_err());
147189

148190
let vote_state = VoteState::default();
149191
let mut vote_account_data: Vec<u8> = vec![0; VoteState::size_of()];
150192
let versioned = VoteStateVersions::new_current(vote_state);
151193
VoteState::serialize(&versioned, &mut vote_account_data).unwrap();
152-
let parsed = parse_account_data(
194+
let parsed = parse_account_data_v2(
153195
&account_pubkey,
154196
&vote_program_id(),
155197
&vote_account_data,
@@ -161,7 +203,7 @@ mod test {
161203

162204
let nonce_data = Versions::new(State::Initialized(Data::default()));
163205
let nonce_account_data = bincode::serialize(&nonce_data).unwrap();
164-
let parsed = parse_account_data(
206+
let parsed = parse_account_data_v2(
165207
&account_pubkey,
166208
&system_program::id(),
167209
&nonce_account_data,

0 commit comments

Comments
 (0)