Fix Rpc inconsistencies (#7826)

* Update rpc account format: remove byte arrays

* Base58-encode pubkeys in getStoragePubkeysForSlot

* Update docs
This commit is contained in:
Tyera Eulberg
2020-01-15 15:33:53 -07:00
committed by GitHub
parent 8ffccfbaff
commit da165d6943
8 changed files with 128 additions and 75 deletions

View File

@ -5,8 +5,9 @@ use crate::{
rpc_client_request::RpcClientRequest,
rpc_request::RpcRequest,
rpc_response::{
Response, RpcBlockhashFeeCalculator, RpcConfirmedBlock, RpcContactInfo, RpcEpochInfo,
RpcLeaderSchedule, RpcResponse, RpcVersionInfo, RpcVoteAccountStatus,
Response, RpcAccount, RpcBlockhashFeeCalculator, RpcConfirmedBlock, RpcContactInfo,
RpcEpochInfo, RpcKeyedAccount, RpcLeaderSchedule, RpcResponse, RpcVersionInfo,
RpcVoteAccountStatus,
},
};
use bincode::serialize;
@ -578,9 +579,16 @@ impl RpcClient {
format!("AccountNotFound: pubkey={}", pubkey),
));
}
let result = serde_json::from_value::<Response<Option<Account>>>(result_json)?;
trace!("Response account {:?} {:?}", pubkey, result);
Ok(result)
let Response {
context,
value: rpc_account,
} = serde_json::from_value::<Response<Option<RpcAccount>>>(result_json)?;
trace!("Response account {:?} {:?}", pubkey, rpc_account);
let account = rpc_account.and_then(|rpc_account| rpc_account.decode().ok());
Ok(Response {
context,
value: account,
})
})
.map_err(|err| {
io::Error::new(
@ -675,8 +683,8 @@ impl RpcClient {
)
})?;
let accounts: Vec<(String, Account)> =
serde_json::from_value::<Vec<(String, Account)>>(response).map_err(|err| {
let accounts: Vec<RpcKeyedAccount> =
serde_json::from_value::<Vec<RpcKeyedAccount>>(response).map_err(|err| {
io::Error::new(
io::ErrorKind::Other,
format!("GetProgramAccounts parse failure: {:?}", err),
@ -684,14 +692,14 @@ impl RpcClient {
})?;
let mut pubkey_accounts: Vec<(Pubkey, Account)> = Vec::new();
for (string, account) in accounts.into_iter() {
let pubkey = string.parse().map_err(|err| {
for RpcKeyedAccount { pubkey, account } in accounts.into_iter() {
let pubkey = pubkey.parse().map_err(|err| {
io::Error::new(
io::ErrorKind::Other,
format!("GetProgramAccounts parse failure: {:?}", err),
)
})?;
pubkey_accounts.push((pubkey, account));
pubkey_accounts.push((pubkey, account.decode().unwrap()));
}
Ok(pubkey_accounts)
}

View File

@ -1,3 +1,4 @@
use crate::rpc_request::RpcError;
use bincode::serialize;
use jsonrpc_core::Result as JsonResult;
use solana_sdk::{
@ -5,9 +6,10 @@ use solana_sdk::{
clock::{Epoch, Slot},
fee_calculator::FeeCalculator,
message::MessageHeader,
pubkey::Pubkey,
transaction::{Result, Transaction},
};
use std::{collections::HashMap, io, net::SocketAddr};
use std::{collections::HashMap, io, net::SocketAddr, str::FromStr};
pub type RpcResponseIn<T> = JsonResult<Response<T>>;
pub type RpcResponse<T> = io::Result<Response<T>>;
@ -145,7 +147,45 @@ pub struct RpcBlockhashFeeCalculator {
#[serde(rename_all = "camelCase")]
pub struct RpcKeyedAccount {
pub pubkey: String,
pub account: Account,
pub account: RpcAccount,
}
/// A duplicate representation of a Message for pretty JSON serialization
#[derive(Serialize, Deserialize, Clone, Debug)]
#[serde(rename_all = "camelCase")]
pub struct RpcAccount {
pub lamports: u64,
pub data: String,
pub owner: String,
pub executable: bool,
pub rent_epoch: Epoch,
}
impl RpcAccount {
pub fn encode(account: Account) -> Self {
RpcAccount {
lamports: account.lamports,
data: bs58::encode(account.data.clone()).into_string(),
owner: account.owner.to_string(),
executable: account.executable,
rent_epoch: account.rent_epoch,
}
}
pub fn decode(&self) -> std::result::Result<Account, RpcError> {
Ok(Account {
lamports: self.lamports,
data: bs58::decode(self.data.clone()).into_vec().map_err(|_| {
RpcError::RpcRequestError("Could not parse encoded account data".to_string())
})?,
owner: Pubkey::from_str(&self.owner).map_err(|_| {
RpcError::RpcRequestError("Could not parse encoded account owner".to_string())
})?,
executable: self.executable,
rent_epoch: self.rent_epoch,
..Account::default()
})
}
}
#[derive(Serialize, Deserialize, Clone, Debug)]