Update getEpochVoteAccounts to getVoteAccounts (#5543)

* Rework getEpochVoteAccounts into getVoteAccounts

* Update client apis

* Update docs

* Review comments
This commit is contained in:
Tyera Eulberg 2019-08-16 17:02:19 -06:00 committed by GitHub
parent 84304cb0fc
commit 8d105042ea
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 79 additions and 46 deletions

View File

@ -26,7 +26,6 @@ Methods
* [getBalance](#getbalance) * [getBalance](#getbalance)
* [getClusterNodes](#getclusternodes) * [getClusterNodes](#getclusternodes)
* [getEpochInfo](#getepochinfo) * [getEpochInfo](#getepochinfo)
* [getEpochVoteAccounts](#getepochvoteaccounts)
* [getLeaderSchedule](#getleaderschedule) * [getLeaderSchedule](#getleaderschedule)
* [getProgramAccounts](#getprogramaccounts) * [getProgramAccounts](#getprogramaccounts)
* [getRecentBlockhash](#getrecentblockhash) * [getRecentBlockhash](#getrecentblockhash)
@ -40,6 +39,7 @@ Methods
* [getTransactionCount](#gettransactioncount) * [getTransactionCount](#gettransactioncount)
* [getTotalSupply](#gettotalsupply) * [getTotalSupply](#gettotalsupply)
* [getVersion](#getversion) * [getVersion](#getversion)
* [getVoteAccounts](#getvoteaccounts)
* [requestAirdrop](#requestairdrop) * [requestAirdrop](#requestairdrop)
* [sendTransaction](#sendtransaction) * [sendTransaction](#sendtransaction)
* [startSubscriptionChannel](#startsubscriptionchannel) * [startSubscriptionChannel](#startsubscriptionchannel)
@ -199,30 +199,6 @@ curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","id":1, "m
--- ---
### getEpochVoteAccounts
Returns the account info and associated stake for all the voting accounts in the current epoch.
##### Parameters:
None
##### Results:
The result field will be an array of JSON objects, each with the following sub fields:
* `votePubkey` - Vote account public key, as base-58 encoded string
* `nodePubkey` - Node public key, as base-58 encoded string
* `stake` - the stake, in lamports, delegated to this vote account
* `commission`, a 32-bit integer used as a fraction (commission/MAX_U32) for rewards payout
##### Example:
```bash
// Request
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","id":1, "method":"getEpochVoteAccounts"}' http://localhost:8899
// Result
{"jsonrpc":"2.0","result":[{"commission":0,"nodePubkey":"Et2RaZJdJRTzTkodUwiHr4H6sLkVmijBFv8tkd7oSSFY","stake":42,"votePubkey":"B4CdWq3NBSoH2wYsVE1CaZSWPo2ZtopE4SJipQhZ3srF"}],"id":1}
```
---
### getLeaderSchedule ### getLeaderSchedule
Returns the leader schedule for the current epoch Returns the leader schedule for the current epoch
@ -498,6 +474,33 @@ curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","id":1, "m
--- ---
### getVoteAccounts
Returns the account info and associated stake for all the voting accounts in the current bank.
##### Parameters:
None
##### Results:
The result field will be a JSON object of `current` and `delinquent` accounts,
each containing an array of JSON objects with the following sub fields:
* `votePubkey` - Vote account public key, as base-58 encoded string
* `nodePubkey` - Node public key, as base-58 encoded string
* `activatedStake` - the stake, in lamports, delegated to this vote account and active in this epoch
* `epochVoteAccount` - bool, whether the vote account is staked for this epoch
* `commission`, an 8-bit integer used as a fraction (commission/MAX_U8) for rewards payout
* `lastVote` - Most recent slot voted on by this vote account
##### Example:
```bash
// Request
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","id":1, "method":"getVoteAccounts"}' http://localhost:8899
// Result
{"jsonrpc":"2.0","result":{"current":[{"commission":0,"epochVoteAccount":true,"nodePubkey":"B97CCUW3AEZFGy6uUg6zUdnNYvnVq5VG8PUtb2HayTDD","lastVote":147,"activatedStake":42,"votePubkey":"3ZT31jkAGhUaw8jsy4bTknwBMP8i4Eueh52By4zXcsVw"}],"delinquent":[{"commission":127,"epochVoteAccount":false,"nodePubkey":"6ZPxeQaDo4bkZLRsdNrCzchNQr5LN9QMc9sipXv9Kw8f","lastVote":0,"activatedStake":0,"votePubkey":"CmgCk4aMS7KW1SHX3s9K5tBJ6Yng2LBaC8MFov4wx9sm"}]},"id":1}
```
---
### requestAirdrop ### requestAirdrop
Requests an airdrop of lamports to a Pubkey Requests an airdrop of lamports to a Pubkey

View File

@ -68,8 +68,8 @@ cluster, as well as the health of the cluster:
```bash ```bash
# Similar to solana-gossip, you should see your validator in the list of cluster nodes # Similar to solana-gossip, you should see your validator in the list of cluster nodes
$ curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","id":1, "method":"getClusterNodes"}' http://testnet.solana.com:8899 $ curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","id":1, "method":"getClusterNodes"}' http://testnet.solana.com:8899
# If your validator is properly staked and voting, it should appear in the list of epoch vote accounts # If your validator is properly voting, it should appear in the list of `current` vote accounts. If staked, `stake` should be > 0
$ curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","id":1, "method":"getEpochVoteAccounts"}' http://testnet.solana.com:8899 $ curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","id":1, "method":"getVoteAccounts"}' http://testnet.solana.com:8899
# Returns the current leader schedule # Returns the current leader schedule
$ curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","id":1, "method":"getLeaderSchedule"}' http://testnet.solana.com:8899 $ curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","id":1, "method":"getLeaderSchedule"}' http://testnet.solana.com:8899
# Returns info about the current epoch. slotIndex should progress on subsequent calls. # Returns info about the current epoch. slotIndex should progress on subsequent calls.

View File

@ -9,7 +9,6 @@ pub enum RpcRequest {
GetAccountInfo, GetAccountInfo,
GetBalance, GetBalance,
GetClusterNodes, GetClusterNodes,
GetEpochVoteAccounts,
GetNumBlocksSinceSignatureConfirmation, GetNumBlocksSinceSignatureConfirmation,
GetProgramAccounts, GetProgramAccounts,
GetRecentBlockhash, GetRecentBlockhash,
@ -22,6 +21,7 @@ pub enum RpcRequest {
GetStoragePubkeysForSlot, GetStoragePubkeysForSlot,
GetTransactionCount, GetTransactionCount,
GetVersion, GetVersion,
GetVoteAccounts,
RegisterNode, RegisterNode,
RequestAirdrop, RequestAirdrop,
SendTransaction, SendTransaction,
@ -38,7 +38,6 @@ impl RpcRequest {
RpcRequest::GetAccountInfo => "getAccountInfo", RpcRequest::GetAccountInfo => "getAccountInfo",
RpcRequest::GetBalance => "getBalance", RpcRequest::GetBalance => "getBalance",
RpcRequest::GetClusterNodes => "getClusterNodes", RpcRequest::GetClusterNodes => "getClusterNodes",
RpcRequest::GetEpochVoteAccounts => "getEpochVoteAccounts",
RpcRequest::GetNumBlocksSinceSignatureConfirmation => { RpcRequest::GetNumBlocksSinceSignatureConfirmation => {
"getNumBlocksSinceSignatureConfirmation" "getNumBlocksSinceSignatureConfirmation"
} }
@ -53,6 +52,7 @@ impl RpcRequest {
RpcRequest::GetStoragePubkeysForSlot => "getStoragePubkeysForSlot", RpcRequest::GetStoragePubkeysForSlot => "getStoragePubkeysForSlot",
RpcRequest::GetTransactionCount => "getTransactionCount", RpcRequest::GetTransactionCount => "getTransactionCount",
RpcRequest::GetVersion => "getVersion", RpcRequest::GetVersion => "getVersion",
RpcRequest::GetVoteAccounts => "getVoteAccounts",
RpcRequest::RegisterNode => "registerNode", RpcRequest::RegisterNode => "registerNode",
RpcRequest::RequestAirdrop => "requestAirdrop", RpcRequest::RequestAirdrop => "requestAirdrop",
RpcRequest::SendTransaction => "sendTransaction", RpcRequest::SendTransaction => "sendTransaction",

View File

@ -16,7 +16,7 @@ use solana_sdk::fee_calculator::FeeCalculator;
use solana_sdk::pubkey::Pubkey; use solana_sdk::pubkey::Pubkey;
use solana_sdk::signature::Signature; use solana_sdk::signature::Signature;
use solana_sdk::transaction::{self, Transaction}; use solana_sdk::transaction::{self, Transaction};
use solana_vote_api::vote_state::VoteState; use solana_vote_api::vote_state::{VoteState, MAX_LOCKOUT_HISTORY};
use std::net::{SocketAddr, UdpSocket}; use std::net::{SocketAddr, UdpSocket};
use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Arc, RwLock}; use std::sync::{Arc, RwLock};
@ -122,22 +122,43 @@ impl JsonRpcRequestProcessor {
Ok(self.bank().capitalization()) Ok(self.bank().capitalization())
} }
fn get_epoch_vote_accounts(&self) -> Result<Vec<RpcVoteAccountInfo>> { fn get_vote_accounts(&self) -> Result<RpcVoteAccountStatus> {
let bank = self.bank(); let bank = self.bank();
Ok(bank let vote_accounts = bank.vote_accounts();
let epoch_vote_accounts = bank
.epoch_vote_accounts(bank.get_epoch_and_slot_index(bank.slot()).0) .epoch_vote_accounts(bank.get_epoch_and_slot_index(bank.slot()).0)
.ok_or_else(Error::invalid_request)? .ok_or_else(Error::invalid_request)?;
let (current_vote_accounts, delinquent_vote_accounts): (
Vec<RpcVoteAccountInfo>,
Vec<RpcVoteAccountInfo>,
) = vote_accounts
.iter() .iter()
.map(|(pubkey, (stake, account))| { .map(|(pubkey, (activated_stake, account))| {
let vote_state = VoteState::from(account).unwrap_or_default(); let vote_state = VoteState::from(&account).unwrap_or_default();
let last_vote = if let Some(vote) = vote_state.votes.iter().last() {
vote.slot
} else {
0
};
let epoch_vote_account = epoch_vote_accounts
.iter()
.any(|(epoch_vote_pubkey, _)| epoch_vote_pubkey == pubkey);
RpcVoteAccountInfo { RpcVoteAccountInfo {
vote_pubkey: (*pubkey).to_string(), vote_pubkey: (pubkey).to_string(),
node_pubkey: vote_state.node_pubkey.to_string(), node_pubkey: vote_state.node_pubkey.to_string(),
stake: *stake, activated_stake: *activated_stake,
commission: vote_state.commission, commission: vote_state.commission,
epoch_vote_account,
last_vote,
} }
}) })
.collect::<Vec<_>>()) .partition(|vote_account_info| {
vote_account_info.last_vote >= bank.slot() - MAX_LOCKOUT_HISTORY as u64
});
Ok(RpcVoteAccountStatus {
current: current_vote_accounts,
delinquent: delinquent_vote_accounts,
})
} }
fn get_storage_turn_rate(&self) -> Result<u64> { fn get_storage_turn_rate(&self) -> Result<u64> {
@ -204,6 +225,12 @@ pub struct RpcContactInfo {
/// JSON RPC port /// JSON RPC port
pub rpc: Option<SocketAddr>, pub rpc: Option<SocketAddr>,
} }
#[derive(Serialize, Deserialize, Clone, Debug)]
#[serde(rename_all = "camelCase")]
pub struct RpcVoteAccountStatus {
pub current: Vec<RpcVoteAccountInfo>,
pub delinquent: Vec<RpcVoteAccountInfo>,
}
#[derive(Serialize, Deserialize, Clone, Debug)] #[derive(Serialize, Deserialize, Clone, Debug)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
@ -215,10 +242,16 @@ pub struct RpcVoteAccountInfo {
pub node_pubkey: String, pub node_pubkey: String,
/// The current stake, in lamports, delegated to this vote account /// The current stake, in lamports, delegated to this vote account
pub stake: u64, pub activated_stake: u64,
/// An 8-bit integer used as a fraction (commission/MAX_U8) for rewards payout /// An 8-bit integer used as a fraction (commission/MAX_U8) for rewards payout
pub commission: u8, pub commission: u8,
/// Whether this account is staked for the current epoch
pub epoch_vote_account: bool,
/// Most recent slot voted on by this vote account
pub last_vote: u64,
} }
#[derive(Serialize, Deserialize, Clone, Debug)] #[derive(Serialize, Deserialize, Clone, Debug)]
@ -294,8 +327,8 @@ pub trait RpcSol {
#[rpc(meta, name = "getSlotLeader")] #[rpc(meta, name = "getSlotLeader")]
fn get_slot_leader(&self, _: Self::Metadata) -> Result<String>; fn get_slot_leader(&self, _: Self::Metadata) -> Result<String>;
#[rpc(meta, name = "getEpochVoteAccounts")] #[rpc(meta, name = "getVoteAccounts")]
fn get_epoch_vote_accounts(&self, _: Self::Metadata) -> Result<Vec<RpcVoteAccountInfo>>; fn get_vote_accounts(&self, _: Self::Metadata) -> Result<RpcVoteAccountStatus>;
#[rpc(meta, name = "getStorageTurnRate")] #[rpc(meta, name = "getStorageTurnRate")]
fn get_storage_turn_rate(&self, _: Self::Metadata) -> Result<u64>; fn get_storage_turn_rate(&self, _: Self::Metadata) -> Result<u64>;
@ -581,11 +614,8 @@ impl RpcSol for RpcSolImpl {
meta.request_processor.read().unwrap().get_slot_leader() meta.request_processor.read().unwrap().get_slot_leader()
} }
fn get_epoch_vote_accounts(&self, meta: Self::Metadata) -> Result<Vec<RpcVoteAccountInfo>> { fn get_vote_accounts(&self, meta: Self::Metadata) -> Result<RpcVoteAccountStatus> {
meta.request_processor meta.request_processor.read().unwrap().get_vote_accounts()
.read()
.unwrap()
.get_epoch_vote_accounts()
} }
fn get_storage_turn_rate(&self, meta: Self::Metadata) -> Result<u64> { fn get_storage_turn_rate(&self, meta: Self::Metadata) -> Result<u64> {