Decode native-program and sysvar accounts (#11463)

* Pass pubkey in to account-decoder for sysvars

* Decode sysvar accounts

* Decode config accounts; move validator-info lower

* Decode stake accounts

* Review comments

* Stringify any account lamports and epochs that can be set to u64::MAX
This commit is contained in:
Tyera Eulberg
2020-08-09 01:50:45 -06:00
committed by GitHub
parent 068d23f298
commit a9f76862fb
16 changed files with 852 additions and 54 deletions

View File

@ -247,7 +247,7 @@ impl JsonRpcRequestProcessor {
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);
response = get_parsed_token_account(bank.clone(), pubkey, 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 {
@ -256,7 +256,7 @@ impl JsonRpcRequestProcessor {
data: None,
});
} else {
response = Some(UiAccount::encode(account, encoding, None));
response = Some(UiAccount::encode(pubkey, account, encoding, None));
}
}
@ -288,7 +288,7 @@ impl JsonRpcRequestProcessor {
keyed_accounts
.map(|(pubkey, account)| RpcKeyedAccount {
pubkey: pubkey.to_string(),
account: UiAccount::encode(account, encoding.clone(), None),
account: UiAccount::encode(&pubkey, account, encoding.clone(), None),
})
.collect()
}
@ -1134,7 +1134,7 @@ impl JsonRpcRequestProcessor {
keyed_accounts
.map(|(pubkey, account)| RpcKeyedAccount {
pubkey: pubkey.to_string(),
account: UiAccount::encode(account, encoding.clone(), None),
account: UiAccount::encode(&pubkey, account, encoding.clone(), None),
})
.collect()
};
@ -1185,7 +1185,7 @@ impl JsonRpcRequestProcessor {
keyed_accounts
.map(|(pubkey, account)| RpcKeyedAccount {
pubkey: pubkey.to_string(),
account: UiAccount::encode(account, encoding.clone(), None),
account: UiAccount::encode(&pubkey, account, encoding.clone(), None),
})
.collect()
};
@ -1242,11 +1242,16 @@ fn get_filtered_program_accounts(
})
}
pub(crate) fn get_parsed_token_account(bank: Arc<Bank>, account: Account) -> Option<UiAccount> {
pub(crate) fn get_parsed_token_account(
bank: Arc<Bank>,
pubkey: &Pubkey,
account: Account,
) -> Option<UiAccount> {
get_token_account_mint(&account.data)
.and_then(|mint_pubkey| get_mint_owner_and_decimals(&bank, &mint_pubkey).ok())
.map(|(_, decimals)| {
UiAccount::encode(
pubkey,
account,
UiAccountEncoding::JsonParsed,
Some(AccountAdditionalData {
@ -1274,6 +1279,7 @@ where
RpcKeyedAccount {
pubkey: pubkey.to_string(),
account: UiAccount::encode(
&pubkey,
account,
UiAccountEncoding::JsonParsed,
Some(AccountAdditionalData { spl_token_decimals }),

View File

@ -672,8 +672,13 @@ mod tests {
.get_account(&nonce_account.pubkey())
.unwrap()
.data;
let expected_data =
parse_account_data(&system_program::id(), &expected_data, None).unwrap();
let expected_data = parse_account_data(
&nonce_account.pubkey(),
&system_program::id(),
&expected_data,
None,
)
.unwrap();
let expected = json!({
"jsonrpc": "2.0",
"method": "accountNotification",

View File

@ -179,7 +179,7 @@ where
K: Eq + Hash + Clone + Copy,
S: Clone + Serialize,
B: Fn(&Bank, &K) -> X,
F: Fn(X, Slot, Option<T>, Option<Arc<Bank>>) -> (Box<dyn Iterator<Item = S>>, Slot),
F: Fn(X, &K, Slot, Option<T>, Option<Arc<Bank>>) -> (Box<dyn Iterator<Item = S>>, Slot),
X: Clone + Serialize + Default,
T: Clone,
{
@ -211,6 +211,7 @@ where
let mut w_last_notified_slot = last_notified_slot.write().unwrap();
let (filter_results, result_slot) = filter_results(
results,
hashmap_key,
*w_last_notified_slot,
config.as_ref().cloned(),
bank,
@ -245,6 +246,7 @@ impl RpcNotifier {
fn filter_account_result(
result: Option<(Account, Slot)>,
pubkey: &Pubkey,
last_notified_slot: Slot,
encoding: Option<UiAccountEncoding>,
bank: Option<Arc<Bank>>,
@ -256,12 +258,14 @@ fn filter_account_result(
let encoding = encoding.unwrap_or(UiAccountEncoding::Binary);
if account.owner == spl_token_id_v1_0() && encoding == UiAccountEncoding::JsonParsed {
let bank = bank.unwrap(); // If result.is_some(), bank must also be Some
if let Some(ui_account) = get_parsed_token_account(bank, account) {
if let Some(ui_account) = get_parsed_token_account(bank, pubkey, account) {
return (Box::new(iter::once(ui_account)), fork);
}
} else {
return (
Box::new(iter::once(UiAccount::encode(account, encoding, None))),
Box::new(iter::once(UiAccount::encode(
pubkey, account, encoding, None,
))),
fork,
);
}
@ -272,6 +276,7 @@ fn filter_account_result(
fn filter_signature_result(
result: Option<transaction::Result<()>>,
_signature: &Signature,
last_notified_slot: Slot,
_config: Option<()>,
_bank: Option<Arc<Bank>>,
@ -288,6 +293,7 @@ fn filter_signature_result(
fn filter_program_results(
accounts: Vec<(Pubkey, Account)>,
_program_id: &Pubkey,
last_notified_slot: Slot,
config: Option<ProgramConfig>,
bank: Option<Arc<Bank>>,
@ -309,7 +315,7 @@ fn filter_program_results(
Box::new(
keyed_accounts.map(move |(pubkey, account)| RpcKeyedAccount {
pubkey: pubkey.to_string(),
account: UiAccount::encode(account, encoding.clone(), None),
account: UiAccount::encode(&pubkey, account, encoding.clone(), None),
}),
)
};