Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use Time instead of u64 seconds in tendermint-testgen Header (master) #1081

Merged
merged 2 commits into from
Jan 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.0", path = "../tendermint" }
tendermint = { version = "0.23.0", path = "../tendermint", features = ["clock"] }
serde = { version = "1", default-features = false, features = ["derive"] }
serde_json = { version = "1", default-features = false, features = ["std"] }
ed25519-consensus = { version = "1.2", 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