use derive_more::Display;
use serde::{Deserialize, Serialize};
use tendermint::{
account::Id as TMAccountId,
block::{
header::Header as TMHeader, signed_header::SignedHeader as TMSignedHeader,
Commit as TMCommit,
},
trust_threshold::TrustThresholdFraction,
validator::Info as TMValidatorInfo,
validator::Set as TMValidatorSet,
};
pub use tendermint::{block::Height, hash::Hash, time::Time};
pub type PeerId = tendermint::node::Id;
pub type TrustThreshold = TrustThresholdFraction;
pub type Header = TMHeader;
pub type ValidatorSet = TMValidatorSet;
pub type Validator = TMValidatorInfo;
pub type ValidatorAddress = TMAccountId;
pub type Commit = TMCommit;
pub type SignedHeader = TMSignedHeader;
pub type TrustedState = LightBlock;
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
pub enum Status {
Failed,
Unverified,
Verified,
Trusted,
}
impl Status {
pub fn iter() -> &'static [Self] {
use Status::*;
static ALL: &[Status] = &[Unverified, Verified, Trusted, Failed];
ALL
}
pub fn most_trusted(a: Self, b: Self) -> Self {
std::cmp::max(a, b)
}
}
#[derive(Clone, Debug, Display, PartialEq, Serialize, Deserialize)]
#[display(fmt = "{:?}", self)]
pub struct LightBlock {
pub signed_header: SignedHeader,
#[serde(rename = "validator_set")]
pub validators: ValidatorSet,
#[serde(rename = "next_validator_set")]
pub next_validators: ValidatorSet,
pub provider: PeerId,
}
impl LightBlock {
pub fn new(
signed_header: SignedHeader,
validators: ValidatorSet,
next_validators: ValidatorSet,
provider: PeerId,
) -> LightBlock {
Self {
signed_header,
validators,
next_validators,
provider,
}
}
pub fn height(&self) -> Height {
self.signed_header.header.height
}
}
#[derive(Clone, Debug, Display, PartialEq, Serialize, Deserialize)]
#[display(fmt = "{:?}", self)]
pub struct LatestStatus {
pub height: Option<u64>,
#[serde(with = "tendermint::serializers::option_hash")]
pub block_hash: Option<Hash>,
#[serde(with = "tendermint::serializers::option_hash")]
pub valset_hash: Option<Hash>,
pub connected_nodes: Vec<PeerId>,
}
impl LatestStatus {
pub fn new(
height: Option<u64>,
block_hash: Option<Hash>,
valset_hash: Option<Hash>,
connected_nodes: Vec<PeerId>,
) -> Self {
Self {
height,
block_hash,
valset_hash,
connected_nodes,
}
}
}
#[cfg(test)]
mod tests {
mod status {
use crate::types::Status;
use Status::*;
#[test]
fn ord_impl() {
assert!(Trusted > Verified);
assert!(Verified > Unverified);
assert!(Unverified > Failed);
}
#[test]
fn most_trusted() {
for (a, b) in cross(Status::iter()) {
if a > b {
assert_eq!(Status::most_trusted(a, b), a);
} else {
assert_eq!(Status::most_trusted(a, b), b);
}
}
}
fn cross<T>(xs: &[T]) -> Vec<(T, T)>
where
T: Copy,
{
xs.iter()
.copied()
.flat_map(|y| xs.iter().copied().map(move |x| (x, y)))
.collect()
}
}
}