Add getEpochInfo() and getLeaderSchedule() RPC methods (#5189)

* Add getLeaderSchedule() RPC method

* Add getEpochInfo() RPC method

* Add JSON RPC docs
This commit is contained in:
Michael Vines 2019-07-19 07:31:18 -07:00 committed by GitHub
parent 83aa609540
commit adfb8ff2a1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 99 additions and 4 deletions

View File

@ -25,6 +25,8 @@ Methods
* [getAccountInfo](#getaccountinfo)
* [getBalance](#getbalance)
* [getClusterNodes](#getclusternodes)
* [getEpochInfo](#getepochinfo)
* [getLeaderSchedule](#getleaderschedule)
* [getProgramAccounts](#getprogramaccounts)
* [getRecentBlockhash](#getrecentblockhash)
* [getSignatureStatus](#getsignaturestatus)
@ -172,6 +174,50 @@ curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0", "id":1, "
---
### getEpochInfo
Returns information about the current epoch
##### Parameters:
None
##### Results:
The result field will be an object with the following fields:
* `epoch`, the current epoch
* `slotIndex`, the current slot relative to the start of the current epoch
* `slotsInEpoch`, the number of slots in this epoch
##### Example:
```bash
// Request
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","id":1, "method":"getEpochInfo"}' http://localhost:8899
// Result
{"jsonrpc":"2.0","result":{"epoch":3,"slotIndex":126,"slotsInEpoch":256},"id":1}
```
---
### getLeaderSchedule
Returns the leader schedule for the current epoch
##### Parameters:
None
##### Results:
The result field will be an array of leader public keys (as base-58 encoded
strings) for each slot in the current epoch
##### Example:
```bash
// Request
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}
```
---
### getProgramAccounts
Returns all accounts owned by the provided program Pubkey

View File

@ -29,6 +29,10 @@ impl LeaderSchedule {
.collect();
Self { slot_leaders }
}
pub(crate) fn get_slot_leaders(&self) -> &[Pubkey] {
&self.slot_leaders
}
}
impl Index<u64> for LeaderSchedule {

View File

@ -5,16 +5,16 @@ use solana_sdk::pubkey::Pubkey;
use solana_sdk::timing::NUM_CONSECUTIVE_LEADER_SLOTS;
/// Return the leader schedule for the given epoch.
pub fn leader_schedule(epoch_height: u64, bank: &Bank) -> Option<LeaderSchedule> {
staking_utils::staked_nodes_at_epoch(bank, epoch_height).map(|stakes| {
pub fn leader_schedule(epoch: u64, bank: &Bank) -> Option<LeaderSchedule> {
staking_utils::staked_nodes_at_epoch(bank, epoch).map(|stakes| {
let mut seed = [0u8; 32];
seed[0..8].copy_from_slice(&epoch_height.to_le_bytes());
seed[0..8].copy_from_slice(&epoch.to_le_bytes());
let mut stakes: Vec<_> = stakes.into_iter().collect();
sort_stakes(&mut stakes);
LeaderSchedule::new(
&stakes,
seed,
bank.get_slots_in_epoch(epoch_height),
bank.get_slots_in_epoch(epoch),
NUM_CONSECUTIVE_LEADER_SLOTS,
)
})

View File

@ -220,6 +220,19 @@ pub struct RpcVoteAccountInfo {
pub commission: u8,
}
#[derive(Serialize, Deserialize, Clone, Debug)]
#[serde(rename_all = "camelCase")]
pub struct RpcEpochInfo {
/// The current epoch
pub epoch: u64,
/// The number of slots in this epoch
pub slots_in_epoch: u64,
/// The current slot, relative to the start of the current epoch
pub slot_index: u64,
}
#[rpc(server)]
pub trait RpcSol {
type Metadata;
@ -239,6 +252,12 @@ pub trait RpcSol {
#[rpc(meta, name = "getClusterNodes")]
fn get_cluster_nodes(&self, _: Self::Metadata) -> Result<Vec<RpcContactInfo>>;
#[rpc(meta, name = "getEpochInfo")]
fn get_epoch_info(&self, _: Self::Metadata) -> Result<RpcEpochInfo>;
#[rpc(meta, name = "getLeaderSchedule")]
fn get_leader_schedule(&self, _: Self::Metadata) -> Result<Option<Vec<String>>>;
#[rpc(meta, name = "getRecentBlockhash")]
fn get_recent_blockhash(&self, _: Self::Metadata) -> Result<(String, FeeCalculator)>;
@ -369,6 +388,32 @@ impl RpcSol for RpcSolImpl {
.collect())
}
fn get_epoch_info(&self, meta: Self::Metadata) -> Result<RpcEpochInfo> {
let bank = meta.request_processor.read().unwrap().bank();
let epoch_schedule = bank.epoch_schedule();
let (epoch, slot_index) = epoch_schedule.get_epoch_and_slot_index(bank.slot());
Ok(RpcEpochInfo {
epoch,
slots_in_epoch: epoch_schedule.get_slots_in_epoch(epoch),
slot_index,
})
}
fn get_leader_schedule(&self, meta: Self::Metadata) -> Result<Option<Vec<String>>> {
let bank = meta.request_processor.read().unwrap().bank();
Ok(
crate::leader_schedule_utils::leader_schedule(bank.epoch(), &bank).map(
|leader_schedule| {
leader_schedule
.get_slot_leaders()
.iter()
.map(|pubkey| pubkey.to_string())
.collect()
},
),
)
}
fn get_recent_blockhash(&self, meta: Self::Metadata) -> Result<(String, FeeCalculator)> {
debug!("get_recent_blockhash rpc request received");
Ok(meta