Rpc: add getLargestAccounts endpoint (#9869) (#9876)

automerge
This commit is contained in:
mergify[bot]
2020-05-04 19:12:18 -07:00
committed by GitHub
parent f951d7d33f
commit 2acf4d874d
5 changed files with 174 additions and 4 deletions

View File

@@ -14,7 +14,7 @@ use jsonrpc_derive::rpc;
use solana_client::rpc_response::*;
use solana_faucet::faucet::request_airdrop_transaction;
use solana_ledger::{bank_forks::BankForks, blockstore::Blockstore};
use solana_runtime::bank::Bank;
use solana_runtime::{accounts::AccountAddressFilter, bank::Bank};
use solana_sdk::{
clock::{Slot, UnixTimestamp},
commitment_config::{CommitmentConfig, CommitmentLevel},
@@ -32,7 +32,7 @@ use solana_transaction_status::{
use solana_vote_program::vote_state::{VoteState, MAX_LOCKOUT_HISTORY};
use std::{
cmp::max,
collections::HashMap,
collections::{HashMap, HashSet},
net::{SocketAddr, UdpSocket},
str::FromStr,
sync::{Arc, RwLock},
@@ -43,6 +43,7 @@ use std::{
const JSON_RPC_SERVER_ERROR_0: i64 = -32000;
const MAX_QUERY_ITEMS: usize = 256;
const MAX_SLOT_RANGE: u64 = 10_000;
const NUM_LARGEST_ACCOUNTS: usize = 20;
type RpcResponse<T> = Result<Response<T>>;
@@ -280,6 +281,27 @@ impl JsonRpcRequestProcessor {
Ok(self.bank(commitment)?.capitalization())
}
fn get_largest_accounts(
&self,
commitment: Option<CommitmentConfig>,
) -> RpcResponse<Vec<RpcAccountBalance>> {
let bank = self.bank(commitment)?;
new_response(
&bank,
bank.get_largest_accounts(
NUM_LARGEST_ACCOUNTS,
&HashSet::new(),
AccountAddressFilter::Exclude,
)
.into_iter()
.map(|(address, lamports)| RpcAccountBalance {
address: address.to_string(),
lamports,
})
.collect(),
)
}
fn get_vote_accounts(
&self,
commitment: Option<CommitmentConfig>,
@@ -733,6 +755,13 @@ pub trait RpcSol {
commitment: Option<CommitmentConfig>,
) -> Result<u64>;
#[rpc(meta, name = "getLargestAccounts")]
fn get_largest_accounts(
&self,
meta: Self::Metadata,
commitment: Option<CommitmentConfig>,
) -> RpcResponse<Vec<RpcAccountBalance>>;
#[rpc(meta, name = "requestAirdrop")]
fn request_airdrop(
&self,
@@ -1134,6 +1163,18 @@ impl RpcSol for RpcSolImpl {
.get_total_supply(commitment)
}
fn get_largest_accounts(
&self,
meta: Self::Metadata,
commitment: Option<CommitmentConfig>,
) -> RpcResponse<Vec<RpcAccountBalance>> {
debug!("get_largest_accounts rpc request received");
meta.request_processor
.read()
.unwrap()
.get_largest_accounts(commitment)
}
fn request_airdrop(
&self,
meta: Self::Metadata,
@@ -1778,6 +1819,49 @@ pub mod tests {
assert!(supply >= TEST_MINT_LAMPORTS);
}
#[test]
fn test_get_largest_accounts() {
let bob_pubkey = Pubkey::new_rand();
let RpcHandler {
io, meta, alice, ..
} = start_rpc_handler_with_tx(&bob_pubkey);
let req = format!(r#"{{"jsonrpc":"2.0","id":1,"method":"getLargestAccounts"}}"#);
let res = io.handle_request_sync(&req, meta.clone());
let json: Value = serde_json::from_str(&res.unwrap()).unwrap();
let largest_accounts: Vec<RpcAccountBalance> =
serde_json::from_value(json["result"]["value"].clone())
.expect("actual response deserialization");
assert_eq!(largest_accounts.len(), 18);
// Get Alice balance
let req = format!(
r#"{{"jsonrpc":"2.0","id":1,"method":"getBalance","params":["{}"]}}"#,
alice.pubkey()
);
let res = io.handle_request_sync(&req, meta.clone());
let json: Value = serde_json::from_str(&res.unwrap()).unwrap();
let alice_balance: u64 = serde_json::from_value(json["result"]["value"].clone())
.expect("actual response deserialization");
assert!(largest_accounts.contains(&RpcAccountBalance {
address: alice.pubkey().to_string(),
lamports: alice_balance,
}));
// Get Bob balance
let req = format!(
r#"{{"jsonrpc":"2.0","id":1,"method":"getBalance","params":["{}"]}}"#,
bob_pubkey
);
let res = io.handle_request_sync(&req, meta);
let json: Value = serde_json::from_str(&res.unwrap()).unwrap();
let bob_balance: u64 = serde_json::from_value(json["result"]["value"].clone())
.expect("actual response deserialization");
assert!(largest_accounts.contains(&RpcAccountBalance {
address: bob_pubkey.to_string(),
lamports: bob_balance,
}));
}
#[test]
fn test_rpc_get_minimum_balance_for_rent_exemption() {
let bob_pubkey = Pubkey::new_rand();