Speed up getLeaderSchedule RPC call by reducing pubkey duplication
This commit is contained in:
parent
6a9005645a
commit
bd22b641b3
|
@ -384,7 +384,9 @@ Returns the leader schedule for an epoch
|
|||
|
||||
#### Results:
|
||||
|
||||
The result field will be an array of leader public keys \(as base-58 encoded strings\) for each slot in the epoch
|
||||
The result field will be a dictionary of leader public keys \(as base-58 encoded
|
||||
strings\) and their corresponding leader slot indices as values (indices are to
|
||||
the first slot in the requested epoch)
|
||||
|
||||
#### Example:
|
||||
|
||||
|
@ -393,7 +395,7 @@ The result field will be an array of leader public keys \(as base-58 encoded str
|
|||
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","id":1, "method":"getLeaderSchedule"}' http://localhost:8899
|
||||
|
||||
// Result
|
||||
{"jsonrpc":"2.0","result":[...],"id":1}
|
||||
{"jsonrpc":"2.0","result":{"4Qkev8aNZcqFNSRhQzwyLMFSsi94jHqE8WNVTJzTP99F":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63]},"id":1}
|
||||
```
|
||||
|
||||
### getMinimumBalanceForRentExemption
|
||||
|
|
|
@ -4,7 +4,10 @@ use crate::{
|
|||
generic_rpc_client_request::GenericRpcClientRequest,
|
||||
mock_rpc_client_request::MockRpcClientRequest,
|
||||
rpc_client_request::RpcClientRequest,
|
||||
rpc_request::{RpcContactInfo, RpcEpochInfo, RpcRequest, RpcVersionInfo, RpcVoteAccountStatus},
|
||||
rpc_request::{
|
||||
RpcContactInfo, RpcEpochInfo, RpcLeaderSchedule, RpcRequest, RpcVersionInfo,
|
||||
RpcVoteAccountStatus,
|
||||
},
|
||||
};
|
||||
use bincode::serialize;
|
||||
use log::*;
|
||||
|
@ -248,7 +251,7 @@ impl RpcClient {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn get_leader_schedule(&self, slot: Option<Slot>) -> io::Result<Option<Vec<String>>> {
|
||||
pub fn get_leader_schedule(&self, slot: Option<Slot>) -> io::Result<Option<RpcLeaderSchedule>> {
|
||||
self.get_leader_schedule_with_commitment(slot, CommitmentConfig::default())
|
||||
}
|
||||
|
||||
|
@ -256,7 +259,7 @@ impl RpcClient {
|
|||
&self,
|
||||
slot: Option<Slot>,
|
||||
commitment_config: CommitmentConfig,
|
||||
) -> io::Result<Option<Vec<String>>> {
|
||||
) -> io::Result<Option<RpcLeaderSchedule>> {
|
||||
let params = slot.map(|slot| json!(slot));
|
||||
let response = self
|
||||
.client
|
||||
|
|
|
@ -6,7 +6,7 @@ use solana_sdk::{
|
|||
hash::Hash,
|
||||
transaction::{Result, Transaction},
|
||||
};
|
||||
use std::{error, fmt, io, net::SocketAddr};
|
||||
use std::{collections::HashMap, error, fmt, io, net::SocketAddr};
|
||||
|
||||
pub type RpcResponseIn<T> = JsonResult<Response<T>>;
|
||||
pub type RpcResponse<T> = io::Result<Response<T>>;
|
||||
|
@ -52,6 +52,9 @@ pub struct RpcContactInfo {
|
|||
pub rpc: Option<SocketAddr>,
|
||||
}
|
||||
|
||||
/// Map of leader base58 identity pubkeys to the slot indices relative to the first epoch slot
|
||||
pub type RpcLeaderSchedule = HashMap<String, Vec<usize>>;
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct RpcEpochInfo {
|
||||
|
|
|
@ -12,8 +12,8 @@ use bincode::serialize;
|
|||
use jsonrpc_core::{Error, Metadata, Result};
|
||||
use jsonrpc_derive::rpc;
|
||||
use solana_client::rpc_request::{
|
||||
Response, RpcConfirmedBlock, RpcContactInfo, RpcEpochInfo, RpcResponseContext, RpcVersionInfo,
|
||||
RpcVoteAccountInfo, RpcVoteAccountStatus,
|
||||
Response, RpcConfirmedBlock, RpcContactInfo, RpcEpochInfo, RpcLeaderSchedule,
|
||||
RpcResponseContext, RpcVersionInfo, RpcVoteAccountInfo, RpcVoteAccountStatus,
|
||||
};
|
||||
use solana_faucet::faucet::request_airdrop_transaction;
|
||||
use solana_ledger::{bank_forks::BankForks, blocktree::Blocktree};
|
||||
|
@ -431,7 +431,7 @@ pub trait RpcSol {
|
|||
meta: Self::Metadata,
|
||||
slot: Option<Slot>,
|
||||
commitment: Option<CommitmentConfig>,
|
||||
) -> Result<Option<Vec<String>>>;
|
||||
) -> Result<Option<RpcLeaderSchedule>>;
|
||||
|
||||
#[rpc(meta, name = "getRecentBlockhash")]
|
||||
fn get_recent_blockhash(
|
||||
|
@ -713,18 +713,23 @@ impl RpcSol for RpcSolImpl {
|
|||
meta: Self::Metadata,
|
||||
slot: Option<Slot>,
|
||||
commitment: Option<CommitmentConfig>,
|
||||
) -> Result<Option<Vec<String>>> {
|
||||
) -> Result<Option<RpcLeaderSchedule>> {
|
||||
let bank = meta.request_processor.read().unwrap().bank(commitment);
|
||||
let slot = slot.unwrap_or_else(|| bank.slot());
|
||||
let epoch = bank.epoch_schedule().get_epoch(slot);
|
||||
|
||||
Ok(
|
||||
solana_ledger::leader_schedule_utils::leader_schedule(epoch, &bank).map(
|
||||
|leader_schedule| {
|
||||
leader_schedule
|
||||
.get_slot_leaders()
|
||||
.iter()
|
||||
.map(|pubkey| pubkey.to_string())
|
||||
.collect()
|
||||
let mut map = HashMap::new();
|
||||
|
||||
for (slot_index, pubkey) in
|
||||
leader_schedule.get_slot_leaders().iter().enumerate()
|
||||
{
|
||||
let pubkey = pubkey.to_string();
|
||||
map.entry(pubkey).or_insert_with(|| vec![]).push(slot_index);
|
||||
}
|
||||
map
|
||||
},
|
||||
),
|
||||
)
|
||||
|
@ -1394,7 +1399,7 @@ pub mod tests {
|
|||
let res: Response = serde_json::from_str(&rep.expect("actual response"))
|
||||
.expect("actual response deserialization");
|
||||
|
||||
let schedule: Option<Vec<String>> = if let Response::Single(res) = res {
|
||||
let schedule: Option<RpcLeaderSchedule> = if let Response::Single(res) = res {
|
||||
if let Output::Success(res) = res {
|
||||
serde_json::from_value(res.result).unwrap()
|
||||
} else {
|
||||
|
@ -1403,9 +1408,14 @@ pub mod tests {
|
|||
} else {
|
||||
panic!("Expected single response");
|
||||
};
|
||||
let schedule = schedule.expect("leader schedule");
|
||||
|
||||
let bob_schedule = schedule
|
||||
.get(&bank.collector_id().to_string())
|
||||
.expect("leader not in the leader schedule");
|
||||
|
||||
assert_eq!(
|
||||
schedule.unwrap().len(),
|
||||
bob_schedule.len(),
|
||||
solana_ledger::leader_schedule_utils::leader_schedule(bank.epoch(), &bank)
|
||||
.unwrap()
|
||||
.get_slot_leaders()
|
||||
|
@ -1418,7 +1428,7 @@ pub mod tests {
|
|||
let res: Response = serde_json::from_str(&rep.expect("actual response"))
|
||||
.expect("actual response deserialization");
|
||||
|
||||
let schedule: Option<Vec<String>> = if let Response::Single(res) = res {
|
||||
let schedule: Option<RpcLeaderSchedule> = if let Response::Single(res) = res {
|
||||
if let Output::Success(res) = res {
|
||||
serde_json::from_value(res.result).unwrap()
|
||||
} else {
|
||||
|
|
Loading…
Reference in New Issue