Skip to content

Commit

Permalink
make the lite client a module instead of a separate crate:
Browse files Browse the repository at this point in the history
This is just the simplest way to move forward implementing the traits of
the lite package. There are alternatives:
We do not want a create a circular dependency between lite and
tendermint (which does not even compile). To avoid this we could:
1) make lite a module of tendermint, or, 2) replicate a lot of the types
of the tendermint crate in the lite package (e.g. Time, Ids etc), or 3)
have a dependency from tendermint to the lite package only (but then the
trait impls do need to live in the lite crate instead with the types in
the tendermint crate directly).
  • Loading branch information
liamsi committed Sep 25, 2019
1 parent 1a232e5 commit d3ce237
Show file tree
Hide file tree
Showing 36 changed files with 70 additions and 49 deletions.
1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,4 @@

members = [
"tendermint",
"lite",
]
7 changes: 0 additions & 7 deletions lite/Cargo.toml

This file was deleted.

2 changes: 0 additions & 2 deletions lite/src/lib.rs

This file was deleted.

2 changes: 1 addition & 1 deletion tendermint/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ authors = [
]

[badges]
circle-ci = { repository = "tendermint/kms" }
circle-ci = { repository = "interchainio/tendermint-rs" }

[dependencies]
byteorder = { version = "1.2" }
Expand Down
25 changes: 23 additions & 2 deletions tendermint/src/block/header.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
//! Block headers

use crate::{account, block, chain, Hash, Time};
use crate::{account, block, chain, lite, Hash, Time};
use {
crate::serializers,
serde::{Deserialize, Serialize},
Expand Down Expand Up @@ -70,6 +69,28 @@ pub struct Header {
pub proposer_address: account::Id,
}

impl lite::Header for Header {
fn height(&self) -> block::Height {
self.height
}

fn bft_time(&self) -> Time {
self.time
}

fn validators_hash(&self) -> Hash {
self.validators_hash
}

fn next_validators_hash(&self) -> Hash {
unimplemented!()
}

fn hash(&self) -> Hash {
unimplemented!()
}
}

/// `Version` contains the protocol version for the blockchain and the
/// application.
///
Expand Down
2 changes: 2 additions & 0 deletions tendermint/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ pub mod consensus;
pub mod evidence;
pub mod genesis;
pub mod hash;
#[allow(dead_code, missing_docs)]
pub mod lite;
pub mod merkle;
mod moniker;
pub mod net;
Expand Down
4 changes: 4 additions & 0 deletions tendermint/src/lite.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
pub use self::types::*;
pub mod types;
pub mod verifier;
pub use self::verifier::*;
22 changes: 9 additions & 13 deletions lite/src/types.rs → tendermint/src/lite/types.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
use std::time::{Duration, Instant};
use crate::account::Id;
use crate::block::Height;
use crate::Hash;
#[allow(clippy::all)]
use crate::Time;

/// TrustedState stores the latest state trusted by a lite client,
/// including the last header and the validator set to use to verify
/// the next header.
Expand All @@ -11,22 +16,13 @@ where
pub validators: V, // height H
}

pub type Height = u64;
/// Size of the underlying Hash in bytes
pub const HASH_LENGTH: usize = 32;
#[derive(Eq, PartialEq)]
pub struct Hash([u8; HASH_LENGTH]);
/// Size of a validator ID in bytes
pub const VAL_ID_LENGTH: usize = 20;
pub struct ValID([u8; VAL_ID_LENGTH]);

/// Header contains meta data about the block -
/// the height, the time, the hash of the validator set
/// that should sign this header, and the hash of the validator
/// set that should sign the next header.
pub trait Header {
fn height(&self) -> Height;
fn bft_time(&self) -> Instant;
fn bft_time(&self) -> Time;
fn validators_hash(&self) -> Hash;
fn next_validators_hash(&self) -> Hash;

Expand Down Expand Up @@ -54,7 +50,7 @@ pub trait ValidatorSet {
/// ValidatorSetLookup allows validator to be fetched via their ID
/// (ie. their address).
pub trait ValidatorSetLookup: ValidatorSet {
fn validator(&self, val_id: ValID) -> Option<Self::Validator>;
fn validator(&self, val_id: Id) -> Option<Self::Validator>;
}

/// Validator has a voting power and can verify
Expand Down Expand Up @@ -90,7 +86,7 @@ pub trait Commit {
/// so each vote is for a slightly different message.
/// Note the Vote must also know which validator it is from.
pub trait Vote {
fn validator_id(&self) -> ValID;
fn validator_id(&self) -> Id;
fn sign_bytes(&self) -> &[u8];
fn signature(&self) -> &[u8];
}
Expand Down
24 changes: 15 additions & 9 deletions lite/src/verifier.rs → tendermint/src/lite/verifier.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
use crate::types::*;
use std::time::{Duration, Instant};
#[allow(clippy::all)]
use crate::lite::{Commit, Error, Header, Validator, ValidatorSet, ValidatorSetLookup, Vote};
use crate::Time;
use std::time::Duration;

/// Returns an error if the header has expired according to the given
/// trusting_period and current time. If so, the verifier must be reset subjectively.
/// NOTE: this doesn't belong here. It should be called by something that handles whether to trust
/// a verifieds commit. Verified here is really just about the header/commit/validators. Time is an
/// a verified commit. Verified here is really just about the header/commit/validators. Time is an
/// external concern :)
fn expired<H>(last_header: &H, trusting_period: Duration, now: Instant) -> Result<(), Error>
fn expired<H>(_last_header: &H, _trusting_period: Duration, _now: Time) -> Result<(), Error>
where
H: Header,
{
if last_header.bft_time() + trusting_period < now {
return Err(Error::Expired);
}
// if let Ok(passed) = now.duration_since(last_header.bft_time()) {
// if passed > trusting_period {
// return Err(Error::Expired);
// }
// }
// TODO move this out of the verifier
// - uncomment above logic but also deal with overflows etc (proper err handling)
Ok(())
}

Expand Down Expand Up @@ -82,7 +88,7 @@ where
}

// ensure that +1/3 of last trusted validators signed correctly
if let Err(e) = verify_commit_trusting(&validators, &commit) {
if let Err(e) = verify_commit_trusting(&last_validators, &commit) {
return Err(e);
}

Expand All @@ -107,7 +113,7 @@ where
return Err(Error::InvalidCommitLength);
}

// The vals and commit have a 1-to-1 correspondance.
// The vals and commit have a 1-to-1 correspondence.
// This means we don't need the validator IDs or to do any lookup,
// we can just zip the iterators.
let vals_iter = vals_vec.into_iter();
Expand Down
14 changes: 8 additions & 6 deletions tendermint/src/net.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,12 +86,14 @@ impl Address {
let (peer_id, authority) = match authority_parts.len() {
1 => (None, authority_parts[0]),
2 => (Some(authority_parts[0].parse()?), authority_parts[1]),
_ => return Err(err!(
ErrorKind::Parse,
"invalid {} address (bad authority): {}",
TCP_PREFIX,
addr
)),
_ => {
return Err(err!(
ErrorKind::Parse,
"invalid {} address (bad authority): {}",
TCP_PREFIX,
addr
))
}
};

let host_and_port: Vec<&str> = authority.split(':').collect();
Expand Down
10 changes: 6 additions & 4 deletions tendermint/src/rpc/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,10 +160,12 @@ impl Client {

let (host, port) = match &self.address {
net::Address::Tcp { host, port, .. } => (host, port),
other => return Err(Error::invalid_params(&format!(
"invalid RPC address: {:?}",
other
))),
other => {
return Err(Error::invalid_params(&format!(
"invalid RPC address: {:?}",
other
)))
}
};

let mut headers = hyper::header::Headers::new();
Expand Down
6 changes: 2 additions & 4 deletions tendermint/src/validator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,8 @@ impl Set {
.into_iter()
.map(|x| x.hash_bytes())
.collect();
let validator_byteslices: Vec<&[u8]> = (&validator_bytes)
.iter()
.map(|x| x.as_slice())
.collect();
let validator_byteslices: Vec<&[u8]> =
(&validator_bytes).iter().map(|x| x.as_slice()).collect();
merkle::simple_hash_from_byte_slices(validator_byteslices.as_slice())
}
}
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

0 comments on commit d3ce237

Please sign in to comment.