Skip to content
This repository has been archived by the owner on Jun 3, 2020. It is now read-only.

Commit

Permalink
tendermint-rs: /validators RPC endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
tony-iqlusion committed Apr 21, 2019
1 parent c55d442 commit 9b911df
Show file tree
Hide file tree
Showing 13 changed files with 751 additions and 56 deletions.
2 changes: 2 additions & 0 deletions tendermint-rs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,9 @@ mod serializers;
pub mod signature;
pub mod timestamp;
pub mod transaction;
pub mod validator;
mod version;
pub mod vote;

#[cfg(feature = "rpc")]
pub use crate::genesis::Genesis;
Expand Down
1 change: 1 addition & 0 deletions tendermint-rs/src/rpc/endpoint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ pub mod block;
pub mod genesis;
pub mod net_info;
pub mod status;
pub mod validators;
2 changes: 1 addition & 1 deletion tendermint-rs/src/rpc/endpoint/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ pub struct Request {

impl Request {
/// Create a new request for information about a particular block
pub fn new<H>(height: block::Height) -> Self {
pub fn new(height: block::Height) -> Self {
Self { height }
}
}
Expand Down
57 changes: 3 additions & 54 deletions tendermint-rs/src/rpc/endpoint/status.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! `/status` endpoint JSONRPC wrapper

use crate::{account, block, node, rpc, Hash, PublicKey, Timestamp};
use serde::{de::Error as DeError, Deserialize, Deserializer, Serialize, Serializer};
use crate::{block, node, rpc, validator, Hash, Timestamp};
use serde::{Deserialize, Serialize};

/// Node status request
#[derive(Debug, Default)]
Expand All @@ -25,7 +25,7 @@ pub struct Response {
pub sync_info: SyncInfo,

/// Validator information
pub validator_info: ValidatorInfo,
pub validator_info: validator::Info,
}

impl rpc::Response for Response {}
Expand All @@ -48,54 +48,3 @@ pub struct SyncInfo {
/// Are we catching up?
pub catching_up: bool,
}

/// Validator information
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct ValidatorInfo {
/// Validator account address
pub address: account::Id,

/// Validator public key
pub pub_key: PublicKey,

/// Validator voting power
pub voting_power: VotingPower,
}

/// Voting power
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
pub struct VotingPower(u64);

impl VotingPower {
/// Get the current voting power
pub fn value(self) -> u64 {
self.0
}

/// Is the current voting power zero?
pub fn is_zero(self) -> bool {
self.0 == 0
}
}

impl From<VotingPower> for u64 {
fn from(power: VotingPower) -> u64 {
power.0
}
}

impl<'de> Deserialize<'de> for VotingPower {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
Ok(VotingPower(
String::deserialize(deserializer)?
.parse()
.map_err(|e| D::Error::custom(format!("{}", e)))?,
))
}
}

impl Serialize for VotingPower {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
self.0.to_string().serialize(serializer)
}
}
39 changes: 39 additions & 0 deletions tendermint-rs/src/rpc/endpoint/validators.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
//! `/validators` endpoint JSONRPC wrapper

use crate::{block, rpc, validator};
use serde::{Deserialize, Serialize};

/// List validators for a specific block
pub struct Request {
height: block::Height,
}

impl Request {
/// List validators for a specific block
pub fn new(height: block::Height) -> Self {
Self { height }
}
}

impl rpc::Request for Request {
type Response = Response;

fn path(&self) -> rpc::request::Path {
// TODO(tarcieri): use a `uri` crate to construct this?
format!("/validators?height={}", self.height)
.parse()
.unwrap()
}
}

/// Validator responses
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct Response {
/// Block height
pub block_height: block::Height,

/// Validator list
pub validators: Vec<validator::Info>,
}

impl rpc::Response for Response {}
57 changes: 57 additions & 0 deletions tendermint-rs/src/validator.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
//! Tendermint validators

use crate::{account, vote, PublicKey};
#[cfg(feature = "serde")]
use serde::{de::Error as DeError, Deserialize, Deserializer, Serialize, Serializer};

/// Validator information
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Clone, Debug)]
pub struct Info {
/// Validator account address
pub address: account::Id,

/// Validator public key
pub pub_key: PublicKey,

/// Validator voting power
pub voting_power: vote::Power,

/// Validator proposer priority
pub proposer_priority: Option<ProposerPriority>,
}

/// Proposer priority
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
pub struct ProposerPriority(i64);

impl ProposerPriority {
/// Get the current voting power
pub fn value(self) -> i64 {
self.0
}
}

impl From<ProposerPriority> for i64 {
fn from(priority: ProposerPriority) -> i64 {
priority.value()
}
}

#[cfg(feature = "serde")]
impl<'de> Deserialize<'de> for ProposerPriority {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
Ok(ProposerPriority(
String::deserialize(deserializer)?
.parse()
.map_err(|e| D::Error::custom(format!("{}", e)))?,
))
}
}

#[cfg(feature = "serde")]
impl Serialize for ProposerPriority {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
self.0.to_string().serialize(serializer)
}
}
44 changes: 44 additions & 0 deletions tendermint-rs/src/vote.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
//! Votes

#[cfg(feature = "serde")]
pub use serde::{de::Error as DeError, Deserialize, Deserializer, Serialize, Serializer};

/// Voting power
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
pub struct Power(u64);

impl Power {
/// Get the current voting power
pub fn value(self) -> u64 {
self.0
}

/// Is the current voting power zero?
pub fn is_zero(self) -> bool {
self.0 == 0
}
}

impl From<Power> for u64 {
fn from(power: Power) -> u64 {
power.0
}
}

#[cfg(feature = "serde")]
impl<'de> Deserialize<'de> for Power {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
Ok(Power(
String::deserialize(deserializer)?
.parse()
.map_err(|e| D::Error::custom(format!("{}", e)))?,
))
}
}

#[cfg(feature = "serde")]
impl Serialize for Power {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
self.0.to_string().serialize(serializer)
}
}
11 changes: 10 additions & 1 deletion tendermint-rs/tests/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ mod endpoints {
use tendermint::rpc::{endpoint, Response};

fn read_json_fixture(name: &str) -> String {
fs::read_to_string(PathBuf::from("./tests/support/").join(name.to_owned() + ".json"))
fs::read_to_string(PathBuf::from("./tests/support/rpc/").join(name.to_owned() + ".json"))
.unwrap()
}

Expand Down Expand Up @@ -71,4 +71,13 @@ mod endpoints {
);
assert_eq!(status_response.validator_info.voting_power.value(), 0);
}

#[test]
fn validators() {
let validators_json = read_json_fixture("validators");
let validators_response =
endpoint::validators::Response::from_json(&validators_json).unwrap();

println!("validators: {:?}", validators_response);
}
}
Loading

0 comments on commit 9b911df

Please sign in to comment.