GetLeaderSchedule can now return a schedule for arbitrary epochs (#7545)
automerge
This commit is contained in:
@ -373,15 +373,16 @@ curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","id":1, "m
|
|||||||
|
|
||||||
### getLeaderSchedule
|
### getLeaderSchedule
|
||||||
|
|
||||||
Returns the leader schedule for the current epoch
|
Returns the leader schedule for an epoch
|
||||||
|
|
||||||
#### Parameters:
|
#### Parameters:
|
||||||
|
|
||||||
|
* `slot` - (optional) Fetch the leader schedule for the epoch that corresponds to the provided slot. If unspecified, the leader schedule for the current epoch is fetch
|
||||||
* `object` - (optional) [Commitment](jsonrpc-api.md#configuring-state-commitment)
|
* `object` - (optional) [Commitment](jsonrpc-api.md#configuring-state-commitment)
|
||||||
|
|
||||||
#### Results:
|
#### Results:
|
||||||
|
|
||||||
The result field will be an array of leader public keys \(as base-58 encoded strings\) for each slot in the current epoch
|
The result field will be an array of leader public keys \(as base-58 encoded strings\) for each slot in the epoch
|
||||||
|
|
||||||
#### Example:
|
#### Example:
|
||||||
|
|
||||||
|
@ -248,6 +248,39 @@ impl RpcClient {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_leader_schedule(&self, slot: Option<Slot>) -> io::Result<Option<Vec<String>>> {
|
||||||
|
self.get_leader_schedule_with_commitment(slot, CommitmentConfig::default())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_leader_schedule_with_commitment(
|
||||||
|
&self,
|
||||||
|
slot: Option<Slot>,
|
||||||
|
commitment_config: CommitmentConfig,
|
||||||
|
) -> io::Result<Option<Vec<String>>> {
|
||||||
|
let params = slot.map(|slot| json!(slot));
|
||||||
|
let response = self
|
||||||
|
.client
|
||||||
|
.send(
|
||||||
|
&RpcRequest::GetLeaderSchedule,
|
||||||
|
params,
|
||||||
|
0,
|
||||||
|
commitment_config.ok(),
|
||||||
|
)
|
||||||
|
.map_err(|err| {
|
||||||
|
io::Error::new(
|
||||||
|
io::ErrorKind::Other,
|
||||||
|
format!("GetLeaderSchedule request failure: {:?}", err),
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
|
||||||
|
serde_json::from_value(response).map_err(|err| {
|
||||||
|
io::Error::new(
|
||||||
|
io::ErrorKind::Other,
|
||||||
|
format!("GetLeaderSchedule failure: {}", err),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_epoch_schedule(&self) -> io::Result<EpochSchedule> {
|
pub fn get_epoch_schedule(&self) -> io::Result<EpochSchedule> {
|
||||||
let response = self
|
let response = self
|
||||||
.client
|
.client
|
||||||
|
@ -121,6 +121,7 @@ pub enum RpcRequest {
|
|||||||
GetEpochSchedule,
|
GetEpochSchedule,
|
||||||
GetGenesisHash,
|
GetGenesisHash,
|
||||||
GetInflation,
|
GetInflation,
|
||||||
|
GetLeaderSchedule,
|
||||||
GetNumBlocksSinceSignatureConfirmation,
|
GetNumBlocksSinceSignatureConfirmation,
|
||||||
GetProgramAccounts,
|
GetProgramAccounts,
|
||||||
GetRecentBlockhash,
|
GetRecentBlockhash,
|
||||||
@ -161,6 +162,7 @@ impl RpcRequest {
|
|||||||
RpcRequest::GetEpochSchedule => "getEpochSchedule",
|
RpcRequest::GetEpochSchedule => "getEpochSchedule",
|
||||||
RpcRequest::GetGenesisHash => "getGenesisHash",
|
RpcRequest::GetGenesisHash => "getGenesisHash",
|
||||||
RpcRequest::GetInflation => "getInflation",
|
RpcRequest::GetInflation => "getInflation",
|
||||||
|
RpcRequest::GetLeaderSchedule => "getLeaderSchedule",
|
||||||
RpcRequest::GetNumBlocksSinceSignatureConfirmation => {
|
RpcRequest::GetNumBlocksSinceSignatureConfirmation => {
|
||||||
"getNumBlocksSinceSignatureConfirmation"
|
"getNumBlocksSinceSignatureConfirmation"
|
||||||
}
|
}
|
||||||
|
@ -418,7 +418,7 @@ pub trait RpcSol {
|
|||||||
fn get_block_commitment(
|
fn get_block_commitment(
|
||||||
&self,
|
&self,
|
||||||
meta: Self::Metadata,
|
meta: Self::Metadata,
|
||||||
block: u64,
|
block: Slot,
|
||||||
) -> Result<(Option<BlockCommitment>, u64)>;
|
) -> Result<(Option<BlockCommitment>, u64)>;
|
||||||
|
|
||||||
#[rpc(meta, name = "getGenesisHash")]
|
#[rpc(meta, name = "getGenesisHash")]
|
||||||
@ -428,6 +428,7 @@ pub trait RpcSol {
|
|||||||
fn get_leader_schedule(
|
fn get_leader_schedule(
|
||||||
&self,
|
&self,
|
||||||
meta: Self::Metadata,
|
meta: Self::Metadata,
|
||||||
|
slot: Option<Slot>,
|
||||||
commitment: Option<CommitmentConfig>,
|
commitment: Option<CommitmentConfig>,
|
||||||
) -> Result<Option<Vec<String>>>;
|
) -> Result<Option<Vec<String>>>;
|
||||||
|
|
||||||
@ -678,8 +679,9 @@ impl RpcSol for RpcSolImpl {
|
|||||||
) -> Result<RpcEpochInfo> {
|
) -> Result<RpcEpochInfo> {
|
||||||
let bank = meta.request_processor.read().unwrap().bank(commitment);
|
let bank = meta.request_processor.read().unwrap().bank(commitment);
|
||||||
let epoch_schedule = bank.epoch_schedule();
|
let epoch_schedule = bank.epoch_schedule();
|
||||||
let (epoch, slot_index) = epoch_schedule.get_epoch_and_slot_index(bank.slot());
|
|
||||||
let slot = bank.slot();
|
let slot = bank.slot();
|
||||||
|
let (epoch, slot_index) = epoch_schedule.get_epoch_and_slot_index(slot);
|
||||||
Ok(RpcEpochInfo {
|
Ok(RpcEpochInfo {
|
||||||
epoch,
|
epoch,
|
||||||
slot_index,
|
slot_index,
|
||||||
@ -708,11 +710,14 @@ impl RpcSol for RpcSolImpl {
|
|||||||
fn get_leader_schedule(
|
fn get_leader_schedule(
|
||||||
&self,
|
&self,
|
||||||
meta: Self::Metadata,
|
meta: Self::Metadata,
|
||||||
|
slot: Option<Slot>,
|
||||||
commitment: Option<CommitmentConfig>,
|
commitment: Option<CommitmentConfig>,
|
||||||
) -> Result<Option<Vec<String>>> {
|
) -> Result<Option<Vec<String>>> {
|
||||||
let bank = meta.request_processor.read().unwrap().bank(commitment);
|
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(
|
Ok(
|
||||||
solana_ledger::leader_schedule_utils::leader_schedule(bank.epoch(), &bank).map(
|
solana_ledger::leader_schedule_utils::leader_schedule(epoch, &bank).map(
|
||||||
|leader_schedule| {
|
|leader_schedule| {
|
||||||
leader_schedule
|
leader_schedule
|
||||||
.get_slot_leaders()
|
.get_slot_leaders()
|
||||||
@ -1337,6 +1342,57 @@ pub mod tests {
|
|||||||
assert_eq!(epoch_schedule, *bank.epoch_schedule());
|
assert_eq!(epoch_schedule, *bank.epoch_schedule());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_rpc_get_leader_schedule() {
|
||||||
|
let bob_pubkey = Pubkey::new_rand();
|
||||||
|
let RpcHandler { io, meta, bank, .. } = start_rpc_handler_with_tx(&bob_pubkey);
|
||||||
|
|
||||||
|
for req in [
|
||||||
|
r#"{"jsonrpc":"2.0","id":1,"method":"getLeaderSchedule", "params": [0]}"#,
|
||||||
|
r#"{"jsonrpc":"2.0","id":1,"method":"getLeaderSchedule"}"#,
|
||||||
|
]
|
||||||
|
.iter()
|
||||||
|
{
|
||||||
|
let rep = io.handle_request_sync(&req, meta.clone());
|
||||||
|
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 {
|
||||||
|
if let Output::Success(res) = res {
|
||||||
|
serde_json::from_value(res.result).unwrap()
|
||||||
|
} else {
|
||||||
|
panic!("Expected success for {}", req);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
panic!("Expected single response");
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
schedule.unwrap().len(),
|
||||||
|
solana_ledger::leader_schedule_utils::leader_schedule(bank.epoch(), &bank)
|
||||||
|
.unwrap()
|
||||||
|
.get_slot_leaders()
|
||||||
|
.len()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let req = r#"{"jsonrpc":"2.0","id":1,"method":"getLeaderSchedule", "params": [42424242]}"#;
|
||||||
|
let rep = io.handle_request_sync(&req, meta);
|
||||||
|
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 {
|
||||||
|
if let Output::Success(res) = res {
|
||||||
|
serde_json::from_value(res.result).unwrap()
|
||||||
|
} else {
|
||||||
|
panic!("Expected success");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
panic!("Expected single response");
|
||||||
|
};
|
||||||
|
assert_eq!(schedule, None);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_rpc_get_account_info() {
|
fn test_rpc_get_account_info() {
|
||||||
let bob_pubkey = Pubkey::new_rand();
|
let bob_pubkey = Pubkey::new_rand();
|
||||||
|
Reference in New Issue
Block a user