Add getEpochInfo() and getLeaderSchedule() RPC methods (#5189)
* Add getLeaderSchedule() RPC method * Add getEpochInfo() RPC method * Add JSON RPC docs
This commit is contained in:
parent
83aa609540
commit
adfb8ff2a1
|
@ -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
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
)
|
||||
})
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue