From bec09671cb68e48f7b37c7535d8ae62c00747a01 Mon Sep 17 00:00:00 2001 From: Michael Vines Date: Tue, 11 Aug 2020 09:14:17 -0700 Subject: [PATCH 1/2] Adapt RpcClient to recent token method changes (#11519) * Avoid skip_serializing_if since that breaks deserialization * Adapt RpcClient to recent token method changes (cherry picked from commit 17645ee20c12b9f1e0002b0453b523f1f9ce0ecb) # Conflicts: # client/src/rpc_client.rs --- account-decoder/src/parse_token.rs | 29 ++--- client/src/rpc_client.rs | 169 +++++------------------------ 2 files changed, 41 insertions(+), 157 deletions(-) diff --git a/account-decoder/src/parse_token.rs b/account-decoder/src/parse_token.rs index 92419b155ed268..459846835d4c25 100644 --- a/account-decoder/src/parse_token.rs +++ b/account-decoder/src/parse_token.rs @@ -45,7 +45,14 @@ pub fn parse_token( }, is_initialized: account.is_initialized, is_native: account.is_native, - delegated_amount: token_amount_to_ui_amount(account.delegated_amount, decimals), + delegated_amount: if account.delegate.is_none() { + None + } else { + Some(token_amount_to_ui_amount( + account.delegated_amount, + decimals, + )) + }, })) } else if data.len() == size_of::() { let mint: Mint = *unpack(&mut data) @@ -102,8 +109,8 @@ pub struct UiTokenAccount { pub delegate: Option, pub is_initialized: bool, pub is_native: bool, - #[serde(skip_serializing_if = "UiTokenAmount::is_zero")] - pub delegated_amount: UiTokenAmount, + #[serde(skip_serializing_if = "Option::is_none")] + pub delegated_amount: Option, } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] @@ -114,16 +121,6 @@ pub struct UiTokenAmount { pub amount: StringAmount, } -impl UiTokenAmount { - fn is_zero(&self) -> bool { - if let Ok(amount) = self.amount.parse::() { - amount == 0 - } else { - false - } - } -} - pub fn token_amount_to_ui_amount(amount: u64, decimals: u8) -> UiTokenAmount { // Use `amount_to_ui_amount()` once spl_token is bumped to a version that supports it: https://github.com/solana-labs/solana-program-library/pull/211 let amount_decimals = amount as f64 / 10_usize.pow(decimals as u32) as f64; @@ -188,11 +185,7 @@ mod test { delegate: None, is_initialized: true, is_native: false, - delegated_amount: UiTokenAmount { - ui_amount: 0.0, - decimals: 2, - amount: "0".to_string() - }, + delegated_amount: None, }), ); diff --git a/client/src/rpc_client.rs b/client/src/rpc_client.rs index 9caec3e9a64194..dfb1370a0bb1cb 100644 --- a/client/src/rpc_client.rs +++ b/client/src/rpc_client.rs @@ -16,10 +16,7 @@ use indicatif::{ProgressBar, ProgressStyle}; use log::*; use serde_json::{json, Value}; use solana_account_decoder::{ - parse_token::{ - get_token_account_mint, parse_token, TokenAccountType, UiMint, UiMultisig, UiTokenAccount, - UiTokenAmount, - }, + parse_token::UiTokenAmount, UiAccount, UiAccountData::{Binary, Binary64}, UiAccountEncoding, @@ -45,7 +42,6 @@ use solana_transaction_status::{ }; use solana_vote_program::vote_state::MAX_LOCKOUT_HISTORY; use std::{ - collections::HashMap, net::SocketAddr, thread::sleep, time::{Duration, Instant}, @@ -711,103 +707,6 @@ impl RpcClient { Ok(hash) } - pub fn get_token_account(&self, pubkey: &Pubkey) -> ClientResult> { - Ok(self - .get_token_account_with_commitment(pubkey, CommitmentConfig::default())? - .value) - } - - pub fn get_token_account_with_commitment( - &self, - pubkey: &Pubkey, - commitment_config: CommitmentConfig, - ) -> RpcResult> { - let Response { - context, - value: account, - } = self.get_account_with_commitment(pubkey, commitment_config)?; - - if account.is_none() { - return Err(RpcError::ForUser(format!("AccountNotFound: pubkey={}", pubkey)).into()); - } - let account = account.unwrap(); - let mint = get_token_account_mint(&account.data) - .and_then(|mint_pubkey| { - self.get_token_mint_with_commitment(&mint_pubkey, commitment_config) - .ok() - .map(|response| response.value) - .flatten() - }) - .ok_or_else(|| { - Into::::into(RpcError::ForUser(format!( - "AccountNotFound: mint for token acccount pubkey={}", - pubkey - ))) - })?; - - Ok(Response { - context, - value: match parse_token(&account.data, Some(mint.decimals)) { - Ok(TokenAccountType::Account(ui_token_account)) => Some(ui_token_account), - _ => None, - }, - }) - } - - pub fn get_token_mint(&self, pubkey: &Pubkey) -> ClientResult> { - Ok(self - .get_token_mint_with_commitment(pubkey, CommitmentConfig::default())? - .value) - } - - pub fn get_token_mint_with_commitment( - &self, - pubkey: &Pubkey, - commitment_config: CommitmentConfig, - ) -> RpcResult> { - let Response { - context, - value: account, - } = self.get_account_with_commitment(pubkey, commitment_config)?; - - Ok(Response { - context, - value: account - .map(|account| match parse_token(&account.data, None) { - Ok(TokenAccountType::Mint(ui_token_mint)) => Some(ui_token_mint), - _ => None, - }) - .flatten(), - }) - } - - pub fn get_token_multisig(&self, pubkey: &Pubkey) -> ClientResult> { - Ok(self - .get_token_multisig_with_commitment(pubkey, CommitmentConfig::default())? - .value) - } - - pub fn get_token_multisig_with_commitment( - &self, - pubkey: &Pubkey, - commitment_config: CommitmentConfig, - ) -> RpcResult> { - let Response { - context, - value: account, - } = self.get_account_with_commitment(pubkey, commitment_config)?; - - Ok(Response { - context, - value: account - .map(|account| match parse_token(&account.data, None) { - Ok(TokenAccountType::Multisig(ui_token_multisig)) => Some(ui_token_multisig), - _ => None, - }) - .flatten(), - }) - } - pub fn get_token_account_balance(&self, pubkey: &Pubkey) -> ClientResult { Ok(self .get_token_account_balance_with_commitment(pubkey, CommitmentConfig::default())? @@ -829,7 +728,7 @@ impl RpcClient { &self, delegate: &Pubkey, token_account_filter: TokenAccountsFilter, - ) -> ClientResult> { + ) -> ClientResult> { Ok(self .get_token_accounts_by_delegate_with_commitment( delegate, @@ -844,39 +743,31 @@ impl RpcClient { delegate: &Pubkey, token_account_filter: TokenAccountsFilter, commitment_config: CommitmentConfig, - ) -> RpcResult> { + ) -> RpcResult> { let token_account_filter = match token_account_filter { TokenAccountsFilter::Mint(mint) => RpcTokenAccountsFilter::Mint(mint.to_string()), TokenAccountsFilter::ProgramId(program_id) => { RpcTokenAccountsFilter::ProgramId(program_id.to_string()) } }; - let Response { - context, - value: accounts, - } = self.send( - RpcRequest::GetTokenAccountsByDelegate, - json!([ - delegate.to_string(), - token_account_filter, - commitment_config - ]), - )?; - let pubkey_accounts = self.accounts_to_token_accounts( - commitment_config, - parse_keyed_accounts(accounts, RpcRequest::GetTokenAccountsByDelegate)?, - ); - Ok(Response { - context, - value: pubkey_accounts, - }) + + let config = RpcAccountInfoConfig { + encoding: Some(UiAccountEncoding::JsonParsed), + commitment: Some(commitment_config), + data_slice: None, + }; + + self.send( + RpcRequest::GetTokenAccountsByOwner, + json!([delegate.to_string(), token_account_filter, config]), + ) } pub fn get_token_accounts_by_owner( &self, owner: &Pubkey, token_account_filter: TokenAccountsFilter, - ) -> ClientResult> { + ) -> ClientResult> { Ok(self .get_token_accounts_by_owner_with_commitment( owner, @@ -891,28 +782,24 @@ impl RpcClient { owner: &Pubkey, token_account_filter: TokenAccountsFilter, commitment_config: CommitmentConfig, - ) -> RpcResult> { + ) -> RpcResult> { let token_account_filter = match token_account_filter { TokenAccountsFilter::Mint(mint) => RpcTokenAccountsFilter::Mint(mint.to_string()), TokenAccountsFilter::ProgramId(program_id) => { RpcTokenAccountsFilter::ProgramId(program_id.to_string()) } }; - let Response { - context, - value: accounts, - } = self.send( + + let config = RpcAccountInfoConfig { + encoding: Some(UiAccountEncoding::JsonParsed), + commitment: Some(commitment_config), + data_slice: None, + }; + + self.send( RpcRequest::GetTokenAccountsByOwner, - json!([owner.to_string(), token_account_filter, commitment_config]), - )?; - let pubkey_accounts = self.accounts_to_token_accounts( - commitment_config, - parse_keyed_accounts(accounts, RpcRequest::GetTokenAccountsByDelegate)?, - ); - Ok(Response { - context, - value: pubkey_accounts, - }) + json!([owner.to_string(), token_account_filter, config]), + ) } pub fn get_token_supply(&self, mint: &Pubkey) -> ClientResult { @@ -932,6 +819,7 @@ impl RpcClient { ) } +<<<<<<< HEAD fn accounts_to_token_accounts( &self, commitment_config: CommitmentConfig, @@ -962,6 +850,9 @@ impl RpcClient { } pub fn poll_balance_with_timeout_and_commitment( +======= + fn poll_balance_with_timeout_and_commitment( +>>>>>>> 17645ee20... Adapt RpcClient to recent token method changes (#11519) &self, pubkey: &Pubkey, polling_frequency: &Duration, From 1c1513b390b49fb832866060baf893d0a4453489 Mon Sep 17 00:00:00 2001 From: Tyera Eulberg Date: Tue, 11 Aug 2020 10:24:19 -0600 Subject: [PATCH 2/2] Fix conflicts --- client/src/rpc_client.rs | 33 --------------------------------- 1 file changed, 33 deletions(-) diff --git a/client/src/rpc_client.rs b/client/src/rpc_client.rs index dfb1370a0bb1cb..ba84eaef4baaa8 100644 --- a/client/src/rpc_client.rs +++ b/client/src/rpc_client.rs @@ -819,40 +819,7 @@ impl RpcClient { ) } -<<<<<<< HEAD - fn accounts_to_token_accounts( - &self, - commitment_config: CommitmentConfig, - pubkey_accounts: Vec<(Pubkey, Account)>, - ) -> Vec<(Pubkey, UiTokenAccount)> { - let mut mint_decimals: HashMap = HashMap::new(); - pubkey_accounts - .into_iter() - .filter_map(|(pubkey, account)| { - let mint_pubkey = get_token_account_mint(&account.data)?; - let decimals = mint_decimals.get(&mint_pubkey).cloned().or_else(|| { - let mint = self - .get_token_mint_with_commitment(&mint_pubkey, commitment_config) - .ok() - .map(|response| response.value) - .flatten()?; - mint_decimals.insert(mint_pubkey, mint.decimals); - Some(mint.decimals) - })?; - match parse_token(&account.data, Some(decimals)) { - Ok(TokenAccountType::Account(ui_token_account)) => { - Some((pubkey, ui_token_account)) - } - _ => None, - } - }) - .collect() - } - pub fn poll_balance_with_timeout_and_commitment( -======= - fn poll_balance_with_timeout_and_commitment( ->>>>>>> 17645ee20... Adapt RpcClient to recent token method changes (#11519) &self, pubkey: &Pubkey, polling_frequency: &Duration,