Skip to content

Commit

Permalink
#414: testgen: add time command; make timestamps abstract
Browse files Browse the repository at this point in the history
  • Loading branch information
andrey-kuprianov committed Aug 10, 2020
1 parent da11fc1 commit 8ff0f93
Show file tree
Hide file tree
Showing 7 changed files with 97 additions and 26 deletions.
5 changes: 4 additions & 1 deletion testgen/bin/tendermint-testgen.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use gumdrop::Options;
use simple_error::SimpleError;
use tendermint_testgen::{helpers::*, Commit, Generator, Header, Validator, Vote};
use tendermint_testgen::{helpers::*, Commit, Generator, Header, Time, Validator, Vote};

const USAGE: &str = r#"
This is a small utility for producing tendermint datastructures
Expand Down Expand Up @@ -65,6 +65,8 @@ enum Command {
Vote(Vote),
#[options(help = "produce commit from validator array and other parameters")]
Commit(Commit),
#[options(help = "produce timestamp from number of seconds since epoch")]
Time(Time),
}

fn encode_with_stdin<Opts: Generator<T> + Options, T: serde::Serialize>(
Expand Down Expand Up @@ -129,5 +131,6 @@ fn main() {
Some(Command::Header(cli)) => run_command(cli, opts.stdin),
Some(Command::Vote(cli)) => run_command(cli, opts.stdin),
Some(Command::Commit(cli)) => run_command(cli, opts.stdin),
Some(Command::Time(cli)) => run_command(cli, opts.stdin),
}
}
18 changes: 8 additions & 10 deletions testgen/src/commit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,26 +152,24 @@ impl Generator<block::Commit> for Commit {
#[cfg(test)]
mod tests {
use super::*;
use tendermint::Time;

#[test]
fn test_commit() {
let valset1 = [
let valset1 = sort_validators(&vec![
Validator::new("a"),
Validator::new("b"),
Validator::new("c"),
];
let valset2 = [
Validator::new("b"),
Validator::new("c"),
]);
let valset2 = sort_validators(&vec![
Validator::new("d"),
];
Validator::new("e"),
Validator::new("f"),
]);

let now = Time::now();
let header = Header::new(&valset1)
.next_validators(&valset2)
.height(10)
.time(now);
.time(11);

let commit = Commit::new(header.clone(), 3);

Expand All @@ -183,7 +181,7 @@ mod tests {

let mut commit = commit;
assert_eq!(commit.vote_at_index(1).round, Some(3));
assert_eq!(commit.vote_of_validator("a").index, Some(0));
assert_eq!(commit.vote_of_validator("b").index, Some(0));

let votes = commit.votes.as_ref().unwrap();

Expand Down
18 changes: 10 additions & 8 deletions testgen/src/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use gumdrop::Options;
use serde::Deserialize;
use simple_error::*;
use std::str::FromStr;
use tendermint::{block, chain, lite::ValidatorSet, validator, Time};
use tendermint::{block, chain, lite::ValidatorSet, validator};

#[derive(Debug, Options, Deserialize, Clone)]
pub struct Header {
Expand All @@ -22,7 +22,7 @@ pub struct Header {
#[options(help = "block height (default: 1)")]
pub height: Option<u64>,
#[options(help = "time (default: now)")]
pub time: Option<Time>,
pub time: Option<u64>,
#[options(help = "proposer index (default: 0)")]
pub proposer: Option<usize>,
}
Expand All @@ -46,7 +46,7 @@ impl Header {
);
set_option!(chain_id, &str, Some(chain_id.to_string()));
set_option!(height, u64);
set_option!(time, Time);
set_option!(time, u64);
set_option!(proposer, usize);
}

Expand Down Expand Up @@ -93,11 +93,14 @@ impl Generator<block::Header> for Header {
Ok(id) => id,
Err(_) => bail!("failed to construct header's chain_id"),
};
let time =
if let Some(t) = self.time { get_time(t) }
else { tendermint::Time::now() };
let header = block::Header {
version: block::header::Version { block: 0, app: 0 },
chain_id,
height: block::Height(self.height.unwrap_or(1)),
time: self.time.unwrap_or_else(Time::now),
time,
last_block_id: None,
last_commit_hash: None,
data_hash: None,
Expand All @@ -116,7 +119,6 @@ impl Generator<block::Header> for Header {
#[cfg(test)]
mod tests {
use super::*;
use std::time::Duration;

#[test]
fn test_header() {
Expand All @@ -131,13 +133,13 @@ mod tests {
Validator::new("d"),
];

let now1 = Time::now();
let now1: u64 = 100;
let header1 = Header::new(&valset1)
.next_validators(&valset2)
.height(10)
.time(now1);

let now2 = now1 + Duration::from_secs(1);
let now2 = now1 + 1;
let header2 = Header::new(&valset1)
.next_validators(&valset2)
.height(10)
Expand All @@ -162,7 +164,7 @@ mod tests {
let header = header2.clone().chain_id("chain1");
assert_eq!(header.generate().unwrap(), block_header);

block_header.proposer_address = Validator::new("b").generate().unwrap().address;
block_header.proposer_address = Validator::new("c").generate().unwrap().address;
assert_ne!(header.generate().unwrap(), block_header);

let header = header.clone().proposer(1);
Expand Down
6 changes: 5 additions & 1 deletion testgen/src/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use signatory::signature::Verifier;
use signatory_dalek::Ed25519Verifier;
use simple_error::*;
use std::io::{self, Read};
use tendermint::{amino_types, signature::Signature, vote};
use tendermint::{amino_types, signature::Signature, vote, Time};

/// A macro that generates a complete setter method from a one-liner with necessary information
#[macro_export]
Expand Down Expand Up @@ -55,3 +55,7 @@ pub fn verify_signature(verifier: &Ed25519Verifier, msg: &[u8], signature: &Sign
tendermint::signature::Signature::Ed25519(sig) => verifier.verify(msg, sig).is_ok(),
}
}

pub fn get_time(abs: u64) -> Time {
(std::time::UNIX_EPOCH + std::time::Duration::from_secs(abs)).into()
}
2 changes: 2 additions & 0 deletions testgen/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ pub mod commit;
pub mod consensus;
pub mod generator;
pub mod header;
pub mod time;
pub mod validator;
pub mod vote;

pub use commit::Commit;
pub use generator::Generator;
pub use header::Header;
pub use time::Time;
pub use validator::Validator;
pub use vote::Vote;
58 changes: 58 additions & 0 deletions testgen/src/time.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
use crate::{helpers::*, Generator};
use gumdrop::Options;
use serde::Deserialize;
use simple_error::*;

#[derive(Debug, Options, Deserialize, Clone)]
pub struct Time {
#[options(help = "seconds passed since UNIX EPOCH (required; can be passed via STDIN)")]
pub secs: Option<u64>,
}

impl Time {
pub fn new(secs: u64) -> Self {
Time {
secs: Some(secs),
}
}
set_option!(secs, u64);
}

impl std::str::FromStr for Time {
type Err = SimpleError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let time = match parse_as::<Time>(s) {
Ok(input) => input,
Err(_) => Time::new(try_with!(u64::from_str(s), "failed to parse time")),
};
Ok(time)
}
}

impl Generator<tendermint::Time> for Time {
fn merge_with_default(self, default: Self) -> Self {
Time {
secs: self.secs.or(default.secs),
}
}

fn generate(&self) -> Result<tendermint::Time, SimpleError> {
let time = match &self.secs {
None => bail!("time is missing"),
Some(secs) => *secs,
};
Ok(get_time(time))
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_time() {

let time = Time::new(0);
assert_eq!(time.generate().unwrap(), tendermint::Time::unix_epoch());
}
}
16 changes: 10 additions & 6 deletions testgen/src/vote.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use signatory::{
signature::{Signature as _, Signer},
};
use simple_error::*;
use tendermint::{block, lite, signature::Signature, vote, Time};
use tendermint::{block, lite, signature::Signature, vote};

use crate::{helpers::*, Generator, Header, Validator};

Expand All @@ -25,7 +25,7 @@ pub struct Vote {
#[options(help = "block height (default: from header)")]
pub height: Option<u64>,
#[options(help = "time (default: from header)")]
pub time: Option<Time>,
pub time: Option<u64>,
#[options(help = "commit round (default: from commit)")]
pub round: Option<u64>,
}
Expand All @@ -46,7 +46,7 @@ impl Vote {
set_option!(header, Header);
set_option!(prevote, bool, if prevote { Some(()) } else { None });
set_option!(height, u64);
set_option!(time, Time);
set_option!(time, u64);
set_option!(round, u64);
}

Expand Down Expand Up @@ -90,6 +90,9 @@ impl Generator<vote::Vote> for Vote {
None => 0 // bail!("failed to generate vote: no index given and validator not present in the header")
}
};
let timestamp =
if let Some(t) = self.time { get_time(t) }
else { block_header.time };
let mut vote = vote::Vote {
vote_type: if self.prevote.is_some() {
vote::Type::Prevote
Expand All @@ -99,7 +102,7 @@ impl Generator<vote::Vote> for Vote {
height: block_header.height,
round: self.round.unwrap_or(1),
block_id: Some(block_id),
timestamp: block_header.time,
timestamp,
validator_address: block_validator.address,
validator_index,
signature: Signature::Ed25519(try_with!(
Expand All @@ -116,6 +119,7 @@ impl Generator<vote::Vote> for Vote {
#[cfg(test)]
mod tests {
use super::*;
use crate::Time;

#[test]
fn test_vote() {
Expand All @@ -130,11 +134,11 @@ mod tests {
Validator::new("d"),
];

let now = Time::now();
let now = Time::new(10).generate().unwrap();
let header = Header::new(&valset1)
.next_validators(&valset2)
.height(10)
.time(now);
.time(10);

let val = &valset1[1];
let vote = Vote::new(val.clone(), header.clone()).round(2);
Expand Down

0 comments on commit 8ff0f93

Please sign in to comment.