Skip to content

Commit

Permalink
Merge pull request #79 from yihuang/optional-last-commit
Browse files Browse the repository at this point in the history
Represent `last_commit` as `Option<Commit>`
  • Loading branch information
liamsi committed Nov 28, 2019
2 parents 2c6a36b + 62159ca commit 22e4b6e
Show file tree
Hide file tree
Showing 5 changed files with 145 additions and 15 deletions.
31 changes: 27 additions & 4 deletions tendermint/src/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ pub mod parts;
mod size;

pub use self::{
commit::Commit,
header::Header,
commit::*,
header::{parse_non_empty_block_id, Header},
height::*,
id::{Id, ParseId},
meta::Meta,
size::Size,
};
use crate::{abci::transaction, evidence};
use serde::{Deserialize, Serialize};
use serde::{Deserialize, Deserializer, Serialize};

/// Blocks consist of a header, transactions, votes (the commit), and a list of
/// evidence of malfeasance (i.e. signing conflicting votes).
Expand All @@ -35,5 +35,28 @@ pub struct Block {
pub evidence: evidence::Data,

/// Last commit
pub last_commit: Commit,
#[serde(deserialize_with = "parse_non_empty_commit")]
pub last_commit: Option<Commit>,
}

pub(crate) fn parse_non_empty_commit<'de, D>(deserializer: D) -> Result<Option<Commit>, D::Error>
where
D: Deserializer<'de>,
{
#[derive(Deserialize)]
struct TmpCommit {
#[serde(deserialize_with = "parse_non_empty_block_id")]
block_id: Option<Id>,
precommits: Option<Precommits>,
}

let commit = TmpCommit::deserialize(deserializer)?;
if commit.block_id.is_none() || commit.precommits.is_none() {
Ok(None)
} else {
Ok(Some(Commit {
block_id: commit.block_id.unwrap(),
precommits: commit.precommits.unwrap(),
}))
}
}
10 changes: 5 additions & 5 deletions tendermint/src/block/commit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,31 +19,31 @@ pub struct Commit {

/// Precommits which certify that a block is valid
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct Precommits(Option<Vec<Option<Vote>>>);
pub struct Precommits(Vec<Option<Vote>>);

impl Precommits {
/// Create a new precommit collection
pub fn new<I>(into_precommits: I) -> Self
where
I: Into<Vec<Option<Vote>>>,
{
Self(Some(into_precommits.into()))
Self(into_precommits.into())
}

/// Convert this collection of precommits into a vector
pub fn into_vec(self) -> Vec<Option<Vote>> {
self.iter().cloned().collect()
self.0.clone()
}

/// Iterate over the precommits in the collection
pub fn iter(&self) -> slice::Iter<'_, Option<Vote>> {
self.as_ref().iter()
self.0.iter()
}
}

impl AsRef<[Option<Vote>]> for Precommits {
fn as_ref(&self) -> &[Option<Vote>] {
self.0.as_ref().map(Vec::as_slice).unwrap_or_else(|| &[])
self.0.as_slice()
}
}

Expand Down
9 changes: 4 additions & 5 deletions tendermint/src/block/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,19 +127,18 @@ impl lite::Header for Header {
}
}

pub(crate) fn parse_non_empty_block_id<'de, D>(
deserializer: D,
) -> Result<Option<block::Id>, D::Error>
/// Parse empty block id as None.
pub fn parse_non_empty_block_id<'de, D>(deserializer: D) -> Result<Option<block::Id>, D::Error>
where
D: Deserializer<'de>,
{
#[derive(Serialize, Deserialize)]
#[derive(Deserialize)]
struct Parts {
#[serde(deserialize_with = "serializers::parse_u64")]
total: u64,
hash: String,
}
#[derive(Serialize, Deserialize)]
#[derive(Deserialize)]
struct BlockId {
hash: String,
parts: Parts,
Expand Down
23 changes: 22 additions & 1 deletion tendermint/tests/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,30 @@ mod endpoints {

assert_eq!(data.iter().len(), 2);
assert_eq!(evidence.iter().len(), 0);
assert_eq!(last_commit.precommits.len(), 65);
assert_eq!(last_commit.unwrap().precommits.len(), 65);
}

#[test]
fn first_block() {
let response =
endpoint::block::Response::from_json(&read_json_fixture("first_block")).unwrap();

let tendermint::Block {
header,
data,
evidence,
last_commit,
} = response.block;

assert_eq!(header.version.block, 10);
assert_eq!(header.chain_id.as_str(), EXAMPLE_CHAIN);
assert_eq!(header.height.value(), 1);
assert!(header.last_block_id.is_none());

assert_eq!(data.iter().len(), 0);
assert_eq!(evidence.iter().len(), 0);
assert!(last_commit.is_none());
}
#[test]
fn block_results() {
let response =
Expand Down
87 changes: 87 additions & 0 deletions tendermint/tests/support/rpc/first_block.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
{
"jsonrpc": "2.0",
"id": "",
"result": {
"block_meta": {
"block_id": {
"hash": "2638F126FC7ABCBCA071B3EFD7207CB11B8F0518D5209717A31115AA9B1F6A68",
"parts": {
"total": "1",
"hash": "E1ACF6037E216A2C455DBBAE23C266ECA07C7F5540CAE9383146D7B20E5CA24D"
}
},
"header": {
"version": {
"block": "10",
"app": "0"
},
"chain_id": "cosmoshub-1",
"height": "1",
"time": "2019-11-20T08:56:48.618137Z",
"num_txs": "0",
"total_txs": "0",
"last_block_id": {
"hash": "",
"parts": {
"total": "0",
"hash": ""
}
},
"last_commit_hash": "",
"data_hash": "",
"validators_hash": "2ADC39A2BA237647FD3D6524739F0952F7AC8BBC895F120403DD4EAA8DCF248A",
"next_validators_hash": "2ADC39A2BA237647FD3D6524739F0952F7AC8BBC895F120403DD4EAA8DCF248A",
"consensus_hash": "048091BC7DDC283F77BFBF91D73C44DA58C3DF8A9CBC867405D8B7F3DAADA22F",
"app_hash": "E0ADD6C9D9C3520D5D5242E2B33FA259FB75B7E2F59C0A2E40FF2493F6C72050",
"last_results_hash": "",
"evidence_hash": "",
"proposer_address": "B84241A54F45F970C173811AF184803264140906"
}
},
"block": {
"header": {
"version": {
"block": "10",
"app": "0"
},
"chain_id": "cosmoshub-1",
"height": "1",
"time": "2019-11-20T08:56:48.618137Z",
"num_txs": "0",
"total_txs": "0",
"last_block_id": {
"hash": "",
"parts": {
"total": "0",
"hash": ""
}
},
"last_commit_hash": "",
"data_hash": "",
"validators_hash": "2ADC39A2BA237647FD3D6524739F0952F7AC8BBC895F120403DD4EAA8DCF248A",
"next_validators_hash": "2ADC39A2BA237647FD3D6524739F0952F7AC8BBC895F120403DD4EAA8DCF248A",
"consensus_hash": "048091BC7DDC283F77BFBF91D73C44DA58C3DF8A9CBC867405D8B7F3DAADA22F",
"app_hash": "E0ADD6C9D9C3520D5D5242E2B33FA259FB75B7E2F59C0A2E40FF2493F6C72050",
"last_results_hash": "",
"evidence_hash": "",
"proposer_address": "B84241A54F45F970C173811AF184803264140906"
},
"data": {
"txs": null
},
"evidence": {
"evidence": null
},
"last_commit": {
"block_id": {
"hash": "",
"parts": {
"total": "0",
"hash": ""
}
},
"precommits": null
}
}
}
}

0 comments on commit 22e4b6e

Please sign in to comment.