From 1988ee9cd6183c4db280bbfa91092d74e253760b Mon Sep 17 00:00:00 2001 From: Tyera Eulberg Date: Wed, 26 Aug 2020 11:39:42 -0600 Subject: [PATCH] Rpc: Filter accounts with invalid mints from get_parsed_token_accounts (#11844) * Filter out accounts with invalid mints from get_parsed_token_accounts * Explicit docs --- core/src/rpc.rs | 43 +++++++++++++++++++++++++++--------- docs/src/apps/jsonrpc-api.md | 6 ++--- 2 files changed, 35 insertions(+), 14 deletions(-) diff --git a/core/src/rpc.rs b/core/src/rpc.rs index 3083e0750e19a1..ee98b433d42747 100644 --- a/core/src/rpc.rs +++ b/core/src/rpc.rs @@ -1328,26 +1328,29 @@ where I: Iterator, { let mut mint_decimals: HashMap = HashMap::new(); - keyed_accounts.map(move |(pubkey, account)| { - let additional_data = get_token_account_mint(&account.data).map(|mint_pubkey| { - let spl_token_decimals = mint_decimals.get(&mint_pubkey).cloned().or_else(|| { - let (_, decimals) = get_mint_owner_and_decimals(&bank, &mint_pubkey).ok()?; - mint_decimals.insert(mint_pubkey, decimals); - Some(decimals) + keyed_accounts.filter_map(move |(pubkey, account)| { + let additional_data = get_token_account_mint(&account.data) + .and_then(|mint_pubkey| { + mint_decimals.get(&mint_pubkey).cloned().or_else(|| { + let (_, decimals) = get_mint_owner_and_decimals(&bank, &mint_pubkey).ok()?; + mint_decimals.insert(mint_pubkey, decimals); + Some(decimals) + }) + }) + .map(|spl_token_decimals| AccountAdditionalData { + spl_token_decimals: Some(spl_token_decimals), }); - AccountAdditionalData { spl_token_decimals } - }); - RpcKeyedAccount { + additional_data.map(|additional_data| RpcKeyedAccount { pubkey: pubkey.to_string(), account: UiAccount::encode( &pubkey, account, UiAccountEncoding::JsonParsed, - additional_data, + Some(additional_data), None, ), - } + }) }) } @@ -4871,6 +4874,24 @@ pub mod tests { serde_json::from_value(result["result"]["value"].clone()).unwrap(); assert_eq!(accounts.len(), 3); + // Test getTokenAccountsByOwner with jsonParsed encoding doesn't return accounts with invalid mints + let req = format!( + r#"{{ + "jsonrpc":"2.0", + "id":1, + "method":"getTokenAccountsByOwner", + "params":["{}", {{"programId": "{}"}}, {{"encoding": "jsonParsed"}}] + }}"#, + owner, + spl_token_id_v1_0(), + ); + let res = io.handle_request_sync(&req, meta.clone()); + let result: Value = serde_json::from_str(&res.expect("actual response")) + .expect("actual response deserialization"); + let accounts: Vec = + serde_json::from_value(result["result"]["value"].clone()).unwrap(); + assert_eq!(accounts.len(), 2); + // Test returns only mint accounts let req = format!( r#"{{ diff --git a/docs/src/apps/jsonrpc-api.md b/docs/src/apps/jsonrpc-api.md index 4772931fdd46d8..fb396f7959309a 100644 --- a/docs/src/apps/jsonrpc-api.md +++ b/docs/src/apps/jsonrpc-api.md @@ -846,7 +846,7 @@ Returns all accounts owned by the provided program Pubkey - `` - (optional) Configuration object containing the following optional fields: - (optional) [Commitment](jsonrpc-api.md#configuring-state-commitment) - `encoding: ` - encoding for Account data, either "base58" (*slow*), "base64" or jsonParsed". - Parsed-JSON encoding attempts to use program-specific state parsers to return more human-readable and explicit account state data. If parsed-JSON is requested but a parser cannot be found, the field falls back to base64 encoding, detectable when the `data` field is type ``. **jsonParsed encoding is UNSTABLE** + Parsed-JSON encoding attempts to use program-specific state parsers to return more human-readable and explicit account state data. If parsed-JSON is requested but a parser cannot be found, the field falls back to base64 encoding, detectable when the `data` field is type ``. If parsed-JSON is requested for the SPL Token program, when a valid mint cannot be found for a particular account, that account will be filtered out from results. **jsonParsed encoding is UNSTABLE** - (optional) `dataSlice: ` - limit the returned account data using the provided `offset: ` and `length: ` fields; only available for "base58" or "base64" encoding. - (optional) `filters: ` - filter results using various [filter objects](jsonrpc-api.md#filters); account must meet all filter criteria to be included in results @@ -1101,7 +1101,7 @@ Returns all SPL Token accounts by approved Delegate. **UNSTABLE** - `` - (optional) Configuration object containing the following optional fields: - (optional) [Commitment](jsonrpc-api.md#configuring-state-commitment) - `encoding: ` - encoding for Account data, either "base58" (*slow*), "base64" or jsonParsed". - Parsed-JSON encoding attempts to use program-specific state parsers to return more human-readable and explicit account state data. If parsed-JSON is requested but a parser cannot be found, the field falls back to binary encoding, detectable when the `data` field is type ``. **jsonParsed encoding is UNSTABLE** + Parsed-JSON encoding attempts to use program-specific state parsers to return more human-readable and explicit account state data. If parsed-JSON is requested but a valid mint cannot be found for a particular account, that account will be filtered out from results. **jsonParsed encoding is UNSTABLE** - (optional) `dataSlice: ` - limit the returned account data using the provided `offset: ` and `length: ` fields; only available for "base58" or "base64" encoding. #### Results: @@ -1138,7 +1138,7 @@ Returns all SPL Token accounts by token owner. **UNSTABLE** - `` - (optional) Configuration object containing the following optional fields: - (optional) [Commitment](jsonrpc-api.md#configuring-state-commitment) - `encoding: ` - encoding for Account data, either "base58" (*slow*), "base64" or jsonParsed". - Parsed-JSON encoding attempts to use program-specific state parsers to return more human-readable and explicit account state data. If parsed-JSON is requested but a parser cannot be found, the field falls back to binary encoding, detectable when the `data` field is type ``. **jsonParsed encoding is UNSTABLE** + Parsed-JSON encoding attempts to use program-specific state parsers to return more human-readable and explicit account state data. If parsed-JSON is requested but a valid mint cannot be found for a particular account, that account will be filtered out from results. **jsonParsed encoding is UNSTABLE** - (optional) `dataSlice: ` - limit the returned account data using the provided `offset: ` and `length: ` fields; only available for "base58" or "base64" encoding. #### Results: