Skip to content

Commit

Permalink
Rpc: Filter accounts with invalid mints from get_parsed_token_accounts (
Browse files Browse the repository at this point in the history
#11844)

* Filter out accounts with invalid mints from get_parsed_token_accounts

* Explicit docs
  • Loading branch information
CriesofCarrots authored Aug 26, 2020
1 parent 2e0fefd commit 1988ee9
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 14 deletions.
43 changes: 32 additions & 11 deletions core/src/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1328,26 +1328,29 @@ where
I: Iterator<Item = (Pubkey, Account)>,
{
let mut mint_decimals: HashMap<Pubkey, u8> = 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,
),
}
})
})
}

Expand Down Expand Up @@ -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<RpcKeyedAccount> =
serde_json::from_value(result["result"]["value"].clone()).unwrap();
assert_eq!(accounts.len(), 2);

// Test returns only mint accounts
let req = format!(
r#"{{
Expand Down
6 changes: 3 additions & 3 deletions docs/src/apps/jsonrpc-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -846,7 +846,7 @@ Returns all accounts owned by the provided program Pubkey
- `<object>` - (optional) Configuration object containing the following optional fields:
- (optional) [Commitment](jsonrpc-api.md#configuring-state-commitment)
- `encoding: <string>` - 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 `<string>`. **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 `<string>`. 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: <object>` - limit the returned account data using the provided `offset: <usize>` and `length: <usize>` fields; only available for "base58" or "base64" encoding.
- (optional) `filters: <array>` - filter results using various [filter objects](jsonrpc-api.md#filters); account must meet all filter criteria to be included in results

Expand Down Expand Up @@ -1101,7 +1101,7 @@ Returns all SPL Token accounts by approved Delegate. **UNSTABLE**
- `<object>` - (optional) Configuration object containing the following optional fields:
- (optional) [Commitment](jsonrpc-api.md#configuring-state-commitment)
- `encoding: <string>` - 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 `<string>`. **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: <object>` - limit the returned account data using the provided `offset: <usize>` and `length: <usize>` fields; only available for "base58" or "base64" encoding.
#### Results:
Expand Down Expand Up @@ -1138,7 +1138,7 @@ Returns all SPL Token accounts by token owner. **UNSTABLE**
- `<object>` - (optional) Configuration object containing the following optional fields:
- (optional) [Commitment](jsonrpc-api.md#configuring-state-commitment)
- `encoding: <string>` - 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 `<string>`. **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: <object>` - limit the returned account data using the provided `offset: <usize>` and `length: <usize>` fields; only available for "base58" or "base64" encoding.
#### Results:
Expand Down

0 comments on commit 1988ee9

Please sign in to comment.