Skip to content

Commit

Permalink
Use Time instead of u64 seconds in tendermint-testgen Header (v0.23) (#…
Browse files Browse the repository at this point in the history
…1080)

* Use Time instead of u64 seconds in tendermint-testgen Header

* Fix testgen time serialization for MBT
  • Loading branch information
soareschen authored Jan 14, 2022
1 parent 7db7c01 commit d560681
Show file tree
Hide file tree
Showing 7 changed files with 58 additions and 22 deletions.
8 changes: 5 additions & 3 deletions light-client/src/supervisor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -585,7 +585,10 @@ mod tests {

let peer_id = provider.unwrap_or("0BEFEEDC0C0ADEADBEBADFADADEFC0FFEEFACADE");

let header = Header::new(&vals).height(1).chain_id(chain).time(1);
let header = Header::new(&vals)
.height(1)
.chain_id(chain)
.time(Time::from_unix_timestamp(1, 0).unwrap());
let commit = Commit::new(header.clone(), 1);
let mut lb = TestgenLightBlock::new(header, commit).provider(peer_id);

Expand Down Expand Up @@ -722,8 +725,7 @@ mod tests {
.collect::<Vec<LightBlock>>();

let mut header = chain.light_blocks[4].header.clone().unwrap();
let mut time = header.time.unwrap();
time += 3;
let time = (header.time.unwrap() + Duration::from_secs(3)).unwrap();
header.time = Some(time);
chain.light_blocks[4].header = Some(header.clone());
chain.light_blocks[4].commit = Some(Commit::new(header, 1));
Expand Down
4 changes: 2 additions & 2 deletions light-client/tests/backward.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

use std::{collections::HashMap, time::Duration};

use tendermint::{hash::Algorithm, Hash};
use tendermint::{hash::Algorithm, Hash, Time};

use tendermint_light_client::{
components::{
Expand Down Expand Up @@ -156,7 +156,7 @@ fn corrupt_hash(mut tc: TestCase, mut rng: TestRng) -> TestCase {
let block = tc.chain.block_mut(height).unwrap();

if let Some(header) = block.header.as_mut() {
header.time = Some(1610105021);
header.time = Some(Time::from_unix_timestamp(1610105021, 0).unwrap());
}

tc
Expand Down
2 changes: 1 addition & 1 deletion testgen/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ description = """
"""

[dependencies]
tendermint = { version = "0.23.4", path = "../tendermint" }
tendermint = { version = "0.23.4", path = "../tendermint", features = ["clock"] }
serde = { version = "1", default-features = false, features = ["derive"] }
serde_json = { version = "1", default-features = false, features = ["std"] }
ed25519-dalek = { version = "1", default-features = false }
Expand Down
3 changes: 2 additions & 1 deletion testgen/src/commit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ impl Generator<block::Commit> for Commit {
#[cfg(test)]
mod tests {
use super::*;
use tendermint::Time;

#[test]
fn test_commit() {
Expand All @@ -186,7 +187,7 @@ mod tests {
let header = Header::new(&valset1)
.next_validators(&valset2)
.height(10)
.time(11);
.time(Time::from_unix_timestamp(11, 0).unwrap());

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

Expand Down
53 changes: 42 additions & 11 deletions testgen/src/header.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use crate::{helpers::*, validator::generate_validators, Generator, Validator};
use core::time::Duration;
use gumdrop::Options;
use serde::{Deserialize, Serialize};
use serde::{Deserializer, Serializer};
use simple_error::*;
use std::convert::{TryFrom, TryInto};
use std::str::FromStr;
Expand All @@ -24,13 +26,41 @@ pub struct Header {
#[options(help = "block height (default: 1)")]
pub height: Option<u64>,
#[options(help = "time (default: now)")]
pub time: Option<u64>,
#[serde(deserialize_with = "deserialize_time")]
#[serde(serialize_with = "serialize_time")]
pub time: Option<Time>,
#[options(help = "proposer index (default: 0)")]
pub proposer: Option<usize>,
#[options(help = "last block id hash (default: Hash::None)")]
pub last_block_id_hash: Option<Hash>,
}

// Serialize and deserialize time only up to second precision for integration with MBT.
// This is ok as long as the serialized form is only used exclusively for MBT.
// Otherwise we will have to find other ways to serialize time at least down to
// millisecond precision, at the same time still being able to support that in MBT.
fn deserialize_time<'de, D>(deserializer: D) -> Result<Option<Time>, D::Error>
where
D: Deserializer<'de>,
{
let m_secs = <Option<i64>>::deserialize(deserializer)?;
let m_time = m_secs.map(|secs| Time::from_unix_timestamp(secs, 0).unwrap());

Ok(m_time)
}

fn serialize_time<S>(m_time: &Option<Time>, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let m_secs = m_time.map(|time| {
let datetime: OffsetDateTime = time.into();
datetime.unix_timestamp()
});

m_secs.serialize(serializer)
}

impl Header {
pub fn new(validators: &[Validator]) -> Self {
Header {
Expand All @@ -51,13 +81,16 @@ impl Header {
);
set_option!(chain_id, &str, Some(chain_id.to_string()));
set_option!(height, u64);
set_option!(time, u64);
set_option!(time, Time);
set_option!(proposer, usize);
set_option!(last_block_id_hash, Hash);

pub fn next(&self) -> Self {
let height = self.height.expect("Missing previous header's height");
let time = self.time.unwrap_or(height); // if no time is found, then we simple correspond it to the header height
// if no time is found, then we simple correspond it to the header height
let time = self
.time
.unwrap_or_else(|| Time::from_unix_timestamp(height.try_into().unwrap(), 0).unwrap());
let validators = self.validators.clone().expect("Missing validators");
let next_validators = self.next_validators.clone().unwrap_or(validators);

Expand All @@ -69,7 +102,7 @@ impl Header {
next_validators: Some(next_validators),
chain_id: self.chain_id.clone(),
height: Some(height + 1),
time: Some(time + 1),
time: Some((time + Duration::from_secs(1)).unwrap()),
proposer: self.proposer, // TODO: proposer must be incremented
last_block_id_hash: Some(last_block_id_hash),
}
Expand Down Expand Up @@ -127,11 +160,7 @@ impl Generator<block::Header> for Header {
Err(_) => bail!("failed to construct header's chain_id"),
};

let time: Time = if let Some(t) = self.time {
get_time(t)?
} else {
OffsetDateTime::now_utc().try_into().unwrap()
};
let time: Time = self.time.unwrap_or_else(Time::now);

let last_block_id = self.last_block_id_hash.map(|hash| block::Id {
hash,
Expand Down Expand Up @@ -164,6 +193,8 @@ impl Generator<block::Header> for Header {
#[cfg(test)]
mod tests {
use super::*;
use core::time::Duration;
use tendermint::Time;

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

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

let now2 = now1 + 1;
let now2 = (now1 + Duration::from_secs(1)).unwrap();
let header2 = Header::new(&valset1)
.next_validators(&valset2)
.height(10)
Expand Down
8 changes: 5 additions & 3 deletions testgen/src/light_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ use crate::{Commit, Generator, Header, Validator};
use tendermint::node::Id as PeerId;
use tendermint::validator;
use tendermint::validator::Set as ValidatorSet;
use tendermint::Time;
use tendermint::{block::signed_header::SignedHeader, Hash};

/// A light block is the core data structure used by the light client.
/// It records everything the light client needs to know about a block.
/// NOTE: This struct & associated `impl` below are a copy of light-client's `LightBlock`.
Expand Down Expand Up @@ -92,7 +94,7 @@ impl LightBlock {
.height(height)
.chain_id("test-chain")
.next_validators(&validators)
.time(height); // just wanted to initialize time with some value
.time(Time::from_unix_timestamp(height as i64, 0).unwrap()); // just wanted to initialize time with some value

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

Expand All @@ -105,7 +107,7 @@ impl LightBlock {
}
}

pub fn new_default_with_time_and_chain_id(chain_id: String, time: u64, height: u64) -> Self {
pub fn new_default_with_time_and_chain_id(chain_id: String, time: Time, height: u64) -> Self {
let validators = [
Validator::new("1").voting_power(50),
Validator::new("2").voting_power(50),
Expand Down Expand Up @@ -295,7 +297,7 @@ mod tests {
let header_6 = Header::new(&validators)
.next_validators(&validators)
.height(10)
.time(10)
.time(Time::from_unix_timestamp(10, 0).unwrap())
.chain_id("test-chain");
let commit_6 = Commit::new(header_6.clone(), 1);
let light_block_6 = LightBlock::new(header_6.clone(), commit_6);
Expand Down
2 changes: 1 addition & 1 deletion testgen/src/vote.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ mod tests {
let header = Header::new(&valset1)
.next_validators(&valset2)
.height(10)
.time(10);
.time(tendermint::Time::from_unix_timestamp(10, 0).unwrap());

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

0 comments on commit d560681

Please sign in to comment.