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

Commit

Permalink
tendermint-rs: /commit RPC endpoint
Browse files Browse the repository at this point in the history
This commit also includes a bunch of new documentation, and renames the
`Timestamp` type to `Time` to better match upstream Tendermint.
  • Loading branch information
tony-iqlusion committed Apr 21, 2019
1 parent 9b911df commit 7fe80dc
Show file tree
Hide file tree
Showing 21 changed files with 1,279 additions and 242 deletions.
10 changes: 5 additions & 5 deletions tendermint-rs/src/amino_types/time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

use crate::{
error::Error,
timestamp::{ParseTimestamp, Timestamp},
time::{ParseTimestamp, Time},
};
use chrono::{TimeZone, Utc};
use std::time::{Duration, SystemTime, UNIX_EPOCH};
Expand All @@ -19,15 +19,15 @@ pub struct TimeMsg {
}

impl ParseTimestamp for TimeMsg {
fn parse_timestamp(&self) -> Result<Timestamp, Error> {
fn parse_timestamp(&self) -> Result<Time, Error> {
Ok(Utc.timestamp(self.seconds, self.nanos as u32).into())
}
}

impl From<Timestamp> for TimeMsg {
fn from(ts: Timestamp) -> TimeMsg {
impl From<Time> for TimeMsg {
fn from(ts: Time) -> TimeMsg {
// TODO: non-panicking method for getting this?
let duration = ts.duration_since(Timestamp::unix_epoch()).unwrap();
let duration = ts.duration_since(Time::unix_epoch()).unwrap();
let seconds = duration.as_secs() as i64;
let nanos = duration.subsec_nanos() as i32;

Expand Down
17 changes: 11 additions & 6 deletions tendermint-rs/src/block.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//! Blocks within the chains of a Tendermint network

mod commit;
pub mod header;
mod height;
mod id;
Expand All @@ -8,28 +9,32 @@ pub mod parts;
mod size;

pub use self::{
commit::LastCommit,
header::Header,
height::*,
id::{Id, ParseId},
meta::Meta,
size::Size,
};
use crate::{commit::LastCommit, evidence, transaction};
use crate::{evidence, transaction};
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};

/// Block data
/// Blocks consist of a header, transactions, votes (the commit), and a list of
/// evidence of malfeasance (i.e. signing conflicting votes).
///
/// <https://github.com/tendermint/tendermint/blob/master/docs/spec/blockchain/blockchain.md#block>
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
#[derive(Clone, Debug)]
pub struct Block {
/// Block header
pub header: Header,

/// Data (i.e. transactions)
pub data: transaction::Collection,
/// Transaction data
pub data: transaction::Data,

/// Evidence of Byzantine behavior
pub evidence: evidence::Collection,
/// Evidence of malfeasance
pub evidence: evidence::Data,

/// Last commit
pub last_commit: LastCommit,
Expand Down
18 changes: 18 additions & 0 deletions tendermint-rs/src/block/commit.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//! Commits to a Tendermint blockchain

use crate::{block, Vote};
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};

/// Last commit to a particular blockchain.
///
/// <https://github.com/tendermint/tendermint/blob/master/docs/spec/blockchain/blockchain.md#lastcommit>
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Clone, Debug)]
pub struct LastCommit {
/// Block ID of the last commit
pub block_id: block::Id,

/// Precommits
pub precommits: Vec<Option<Vote>>,
}
35 changes: 21 additions & 14 deletions tendermint-rs/src/block/header.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
//! Block headers

use crate::{account, block, chain, Hash, Timestamp};
use crate::{account, block, chain, Hash, Time};
#[cfg(feature = "serde")]
use {
crate::serializers,
serde::{Deserialize, Serialize},
};

/// Block header
/// Block `Header` values contain metadata about the block and about the
/// consensus, as well as commitments to the data in the current block, the
/// previous block, and the results returned by the application.
///
/// <https://github.com/tendermint/tendermint/blob/master/docs/spec/blockchain/blockchain.md#header>
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Clone, Debug)]
pub struct Header {
Expand All @@ -21,7 +25,7 @@ pub struct Header {
pub height: block::Height,

/// Current timestamp
pub time: Timestamp,
pub time: Time,

/// Number of transactions in block
#[cfg_attr(
Expand All @@ -43,38 +47,41 @@ pub struct Header {
)]
pub total_txs: u64,

/// Last block ID
/// Previous block info
pub last_block_id: block::Id,

/// Last commit hash
/// Commit from validators from the last block
pub last_commit_hash: Hash,

/// Data hash
/// Merkle root of transaction hashes
pub data_hash: Hash,

/// Validators hash
/// Validators for the current block
pub validators_hash: Hash,

/// Next validators hash
/// Validators for the next block
pub next_validators_hash: Hash,

/// Consensus hash
/// Consensus params for the current block
pub consensus_hash: Hash,

/// App hash
/// State after txs from the previous block
pub app_hash: Hash,

/// Last results hash
/// Root hash of all results from the txs from the previous block
pub last_results_hash: Hash,

/// Evidence hash
/// Hash of evidence included in the block
pub evidence_hash: Hash,

/// Proposer address
/// Original proposer of the block
pub proposer_address: account::Id,
}

/// Block header versions
/// `Version` contains the protocol version for the blockchain and the
/// application.
///
/// <https://github.com/tendermint/tendermint/blob/master/docs/spec/blockchain/blockchain.md#version>
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Clone, Debug)]
pub struct Version {
Expand Down
21 changes: 18 additions & 3 deletions tendermint-rs/src/block/id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,29 @@ use std::{
str::{self, FromStr},
};

/// Block identifiers
/// Block identifiers which contain two distinct Merkle roots of the block,
/// as well as the number of parts in the block.
///
/// <https://github.com/tendermint/tendermint/blob/master/docs/spec/blockchain/blockchain.md#blockid>
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Clone, Debug, Hash, Eq, PartialEq)]
pub struct Id {
/// Hash which identifies this block
/// The block's main hash is the Merkle root of all the fields in the
/// block header.
pub hash: Hash,

/// Parts header (if available)
/// Parts header (if available) is used for secure gossipping of the block
/// during consensus. It is the Merkle root of the complete serialized block
/// cut into parts.
///
/// PartSet is used to split a byteslice of data into parts (pieces) for
/// transmission. By splitting data into smaller parts and computing a
/// Merkle root hash on the list, you can verify that a part is
/// legitimately part of the complete data, and the part can be forwarded
/// to other peers before all the parts are known. In short, it's a fast
/// way to propagate a large file over a gossip network.
///
/// <https://github.com/tendermint/tendermint/wiki/Block-Structure#partset>
pub parts: Option<parts::Header>,
}

Expand Down
4 changes: 2 additions & 2 deletions tendermint-rs/src/chain/info.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{block, chain, timestamp::Timestamp};
use crate::{block, chain, time::Time};

/// Information about a particular Tendermint blockchain
#[derive(Clone, Debug)]
Expand All @@ -13,7 +13,7 @@ pub struct Info {
pub last_block_id: Option<block::Id>,

/// Current consensus time (if available)
pub time: Option<Timestamp>,
pub time: Option<Time>,
}

impl Info {
Expand Down
64 changes: 0 additions & 64 deletions tendermint-rs/src/commit.rs

This file was deleted.

39 changes: 22 additions & 17 deletions tendermint-rs/src/evidence.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! Evidence of Byzantine behavior
//! Evidence of malfeasance by validators (i.e. signing conflicting votes).

use std::slice;
#[cfg(feature = "serde")]
Expand All @@ -8,8 +8,11 @@ use {
subtle_encoding::base64,
};

/// Evidence data
// TODO(tarcieri): parse evidence (amino?)
/// Evidence of malfeasance by validators (i.e. signing conflicting votes).
/// encoded using an Amino prefix. There is currently only a single type of
/// evidence: `DuplicateVoteEvidence`.
///
/// <https://github.com/tendermint/tendermint/blob/master/docs/spec/blockchain/blockchain.md#evidence>
#[derive(Clone, Debug)]
pub struct Evidence(Vec<u8>);

Expand All @@ -19,12 +22,12 @@ impl Evidence {
where
V: Into<Vec<u8>>,
{
// TODO(tarcieri): parse/validate evidence contents
// TODO(tarcieri): parse/validate evidence contents from amino messages
Evidence(into_vec.into())
}

/// Serialize this evidence as a bytestring
pub fn to_bytes(&self) -> Vec<u8> {
/// Serialize this evidence as an Amino message bytestring
pub fn to_amino_bytes(&self) -> Vec<u8> {
self.0.clone()
}
}
Expand All @@ -42,46 +45,48 @@ impl<'de> Deserialize<'de> for Evidence {
#[cfg(feature = "serde")]
impl Serialize for Evidence {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
String::from_utf8(base64::encode(self.to_bytes()))
String::from_utf8(base64::encode(self.to_amino_bytes()))
.unwrap()
.serialize(serializer)
}
}

/// Evidence collection
/// Evidence data is a wrapper for a list of `Evidence`.
///
/// <https://github.com/tendermint/tendermint/blob/master/docs/spec/blockchain/blockchain.md#evidencedata>
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
#[derive(Clone, Debug)]
pub struct Collection {
pub struct Data {
evidence: Option<Vec<Evidence>>,
}

impl Collection {
/// Create a new evidence collection
pub fn new<I>(into_evidence: I) -> Collection
impl Data {
/// Create a new evidence data collection
pub fn new<I>(into_evidence: I) -> Data
where
I: Into<Vec<Evidence>>,
{
Collection {
Data {
evidence: Some(into_evidence.into()),
}
}

/// Convert this collection into a vector
/// Convert this evidence data into a vector
pub fn into_vec(self) -> Vec<Evidence> {
self.evidence.unwrap_or_else(|| vec![])
}

/// Iterate over the evidence in the collection
/// Iterate over the evidence data
pub fn iter(&self) -> slice::Iter<Evidence> {
self.as_ref().iter()
}
}

impl AsRef<[Evidence]> for Collection {
impl AsRef<[Evidence]> for Data {
fn as_ref(&self) -> &[Evidence] {
self.evidence
.as_ref()
.map(|evidence| evidence.as_slice())
.map(Vec::as_slice)
.unwrap_or_else(|| &[])
}
}
Expand Down
Loading

0 comments on commit 7fe80dc

Please sign in to comment.