Skip to content
This repository was archived by the owner on Jan 22, 2025. It is now read-only.

Commit

Permalink
Add Binary64 option for account data
Browse files Browse the repository at this point in the history
  • Loading branch information
sakridge committed Aug 8, 2020
1 parent 9215294 commit ae10f23
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 17 deletions.
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.

1 change: 1 addition & 0 deletions account-decoder/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ license = "Apache-2.0"
edition = "2018"

[dependencies]
base64 = "0.12.3"
bincode = "1.3.1"
bs58 = "0.3.1"
Inflector = "0.11.4"
Expand Down
4 changes: 4 additions & 0 deletions account-decoder/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ pub struct UiAccount {
pub enum UiAccountData {
Binary(String),
Json(ParsedAccount),
Binary64(String),
}

impl From<Vec<u8>> for UiAccountData {
Expand All @@ -43,6 +44,7 @@ impl From<Vec<u8>> for UiAccountData {
pub enum UiAccountEncoding {
Binary,
JsonParsed,
Binary64,
}

impl UiAccount {
Expand All @@ -53,6 +55,7 @@ impl UiAccount {
) -> Self {
let data = match encoding {
UiAccountEncoding::Binary => account.data.into(),
UiAccountEncoding::Binary64 => UiAccountData::Binary64(base64::encode(account.data)),
UiAccountEncoding::JsonParsed => {
if let Ok(parsed_data) =
parse_account_data(&account.owner, &account.data, additional_data)
Expand All @@ -76,6 +79,7 @@ impl UiAccount {
let data = match &self.data {
UiAccountData::Json(_) => None,
UiAccountData::Binary(blob) => bs58::decode(blob).into_vec().ok(),
UiAccountData::Binary64(blob) => base64::decode(blob).ok(),
}?;
Some(Account {
lamports: self.lamports,
Expand Down
9 changes: 7 additions & 2 deletions client/src/rpc_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::{
client_error::{ClientError, ClientErrorKind, Result as ClientResult},
http_sender::HttpSender,
mock_sender::{MockSender, Mocks},
rpc_config::RpcAccountInfoConfig,
rpc_config::{
RpcGetConfirmedSignaturesForAddress2Config, RpcLargestAccountsConfig,
RpcSendTransactionConfig, RpcTokenAccountsFilter,
Expand All @@ -19,7 +20,7 @@ use solana_account_decoder::{
get_token_account_mint, parse_token, TokenAccountType, UiMint, UiMultisig, UiTokenAccount,
UiTokenAmount,
},
UiAccount,
UiAccount, UiAccountEncoding,
};
use solana_sdk::{
account::Account,
Expand Down Expand Up @@ -466,9 +467,13 @@ impl RpcClient {
pubkey: &Pubkey,
commitment_config: CommitmentConfig,
) -> RpcResult<Option<Account>> {
let config = RpcAccountInfoConfig {
encoding: Some(UiAccountEncoding::Binary64),
commitment: Some(commitment_config),
};
let response = self.sender.send(
RpcRequest::GetAccountInfo,
json!([pubkey.to_string(), commitment_config]),
json!([pubkey.to_string(), config]),
);

response
Expand Down
34 changes: 20 additions & 14 deletions core/src/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::{
rpc_health::*, validator::ValidatorExit,
};
use bincode::{config::Options, serialize};
use jsonrpc_core::{Error, Metadata, Result};
use jsonrpc_core::{types::error, Error, Metadata, Result};
use jsonrpc_derive::rpc;
use solana_account_decoder::{
parse_account_data::AccountAdditionalData,
Expand Down Expand Up @@ -240,21 +240,27 @@ impl JsonRpcRequestProcessor {
&self,
pubkey: &Pubkey,
config: Option<RpcAccountInfoConfig>,
) -> RpcResponse<Option<UiAccount>> {
) -> Result<RpcResponse<Option<UiAccount>>> {
let config = config.unwrap_or_default();
let bank = self.bank(config.commitment);
let encoding = config.encoding.unwrap_or(UiAccountEncoding::Binary);
new_response(
&bank,
bank.get_account(pubkey).and_then(|account| {
if account.owner == spl_token_id_v1_0() && encoding == UiAccountEncoding::JsonParsed
{
get_parsed_token_account(bank.clone(), account)
} else {
Some(UiAccount::encode(account, encoding, None))
}
}),
)
let mut response = None;
if let Some(account) = bank.get_account(pubkey) {
if account.owner == spl_token_id_v1_0() && encoding == UiAccountEncoding::JsonParsed {
response = get_parsed_token_account(bank.clone(), account);
} else if encoding == UiAccountEncoding::Binary && account.data.len() > 128 {
let message = "Encoded binary (bs58) data should be less than 128, please use Binary64 encoding".to_string();
return Err(error::Error {
code: error::ErrorCode::InvalidRequest,
message,
data: None,
});
} else {
response = Some(UiAccount::encode(account, encoding, None));
}
}

Ok(new_response(&bank, response))
}

pub fn get_minimum_balance_for_rent_exemption(
Expand Down Expand Up @@ -1701,7 +1707,7 @@ impl RpcSol for RpcSolImpl {
) -> Result<RpcResponse<Option<UiAccount>>> {
debug!("get_account_info rpc request received: {:?}", pubkey_str);
let pubkey = verify_pubkey(pubkey_str)?;
Ok(meta.get_account_info(&pubkey, config))
meta.get_account_info(&pubkey, config)
}

fn get_minimum_balance_for_rent_exemption(
Expand Down
13 changes: 13 additions & 0 deletions core/tests/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,19 @@ fn test_rpc_send_tx() {

assert_eq!(confirmed_tx, true);

use solana_account_decoder::UiAccountEncoding;
use solana_client::rpc_config::RpcAccountInfoConfig;
let config = RpcAccountInfoConfig {
encoding: Some(UiAccountEncoding::Binary64),
commitment: None,
};
let req = json_req!(
"getAccountInfo",
json!([bs58::encode(bob_pubkey).into_string(), config])
);
let json: Value = post_rpc(req, &leader_data);
info!("{:?}", json["result"]["value"]);

server.close().unwrap();
remove_dir_all(ledger_path).unwrap();
}
Expand Down
2 changes: 1 addition & 1 deletion docs/src/apps/jsonrpc-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ Returns all information associated with the account of provided Pubkey
- `<string>` - Pubkey of account to query, as base-58 encoded string
- `<object>` - (optional) Configuration object containing the following optional fields:
- (optional) [Commitment](jsonrpc-api.md#configuring-state-commitment)
- (optional) `encoding: <string>` - encoding for Account data, either "binary" or jsonParsed". If parameter not provided, the default encoding is binary.
- (optional) `encoding: <string>` - encoding for Account data, either "binary", "binary64", or jsonParsed". If parameter not provided, the default encoding is "binary". "binary" is bs58 encoded and limited to data queries of less than 128 bytes. Binary64 will return base64 encoded data.
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**

#### Results:
Expand Down

0 comments on commit ae10f23

Please sign in to comment.