Add Binary64 option for account data (#11474)
* Add Binary64 option for account data * Decode into binary64 * Reword docs
This commit is contained in:
parent
4d918f83ff
commit
068d23f298
|
@ -3204,6 +3204,7 @@ name = "solana-account-decoder"
|
|||
version = "1.4.0"
|
||||
dependencies = [
|
||||
"Inflector",
|
||||
"base64 0.12.3",
|
||||
"bincode",
|
||||
"bs58",
|
||||
"lazy_static",
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -30,6 +30,7 @@ pub struct UiAccount {
|
|||
pub enum UiAccountData {
|
||||
Binary(String),
|
||||
Json(ParsedAccount),
|
||||
Binary64(String),
|
||||
}
|
||||
|
||||
impl From<Vec<u8>> for UiAccountData {
|
||||
|
@ -43,6 +44,7 @@ impl From<Vec<u8>> for UiAccountData {
|
|||
pub enum UiAccountEncoding {
|
||||
Binary,
|
||||
JsonParsed,
|
||||
Binary64,
|
||||
}
|
||||
|
||||
impl UiAccount {
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
|
|
|
@ -350,7 +350,7 @@ mod tests {
|
|||
)
|
||||
.unwrap();
|
||||
let nonce_pubkey = Pubkey::new(&[4u8; 32]);
|
||||
let rpc_nonce_account = UiAccount::encode(nonce_account, UiAccountEncoding::Binary, None);
|
||||
let rpc_nonce_account = UiAccount::encode(nonce_account, UiAccountEncoding::Binary64, None);
|
||||
let get_account_response = json!(Response {
|
||||
context: RpcResponseContext { slot: 1 },
|
||||
value: json!(Some(rpc_nonce_account)),
|
||||
|
|
|
@ -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,
|
||||
|
@ -20,6 +21,8 @@ use solana_account_decoder::{
|
|||
UiTokenAmount,
|
||||
},
|
||||
UiAccount,
|
||||
UiAccountData::{Binary, Binary64},
|
||||
UiAccountEncoding,
|
||||
};
|
||||
use solana_sdk::{
|
||||
account::Account,
|
||||
|
@ -466,9 +469,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
|
||||
|
@ -480,8 +487,17 @@ impl RpcClient {
|
|||
}
|
||||
let Response {
|
||||
context,
|
||||
value: rpc_account,
|
||||
value: mut rpc_account,
|
||||
} = serde_json::from_value::<Response<Option<UiAccount>>>(result_json)?;
|
||||
if let Some(ref mut account) = rpc_account {
|
||||
if let Binary(_) = &account.data {
|
||||
let tmp = Binary64(String::new());
|
||||
match std::mem::replace(&mut account.data, tmp) {
|
||||
Binary(new_data) => account.data = Binary64(new_data),
|
||||
_ => panic!("should have gotten binary here."),
|
||||
}
|
||||
}
|
||||
}
|
||||
trace!("Response account {:?} {:?}", pubkey, rpc_account);
|
||||
let account = rpc_account.and_then(|rpc_account| rpc_account.decode());
|
||||
Ok(Response {
|
||||
|
|
|
@ -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,
|
||||
|
@ -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 (base 58) data should be less than 128 bytes, 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(
|
||||
|
@ -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(
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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 base-58 encoded and limited to Account data of less than 128 bytes. "binary64" will return base64 encoded data for Account data of any size.
|
||||
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:
|
||||
|
|
Loading…
Reference in New Issue