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

Split out verifier parts of tendermint-light-client to tendermint-light-client-verifier #1071

Merged
merged 4 commits into from
Jan 12, 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
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
- `[tendermint-light-client]` Split out the verification functionality from the
`tendermint-light-client` crate into its own `no_std`-compatible crate:
`tendermint-light-client-verifier`. This helps move us closer to `no_std`
compliance in both tendermint-rs and ibc-rs
([#1027](https://github.com/informalsystems/tendermint-rs/issues/1027))
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ members = [
"config",
"light-client",
"light-client-js",
"light-client-verifier",
"p2p",
"pbt-gen",
"proto",
Expand Down
2 changes: 1 addition & 1 deletion light-client-js/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ serde_json = { version = "1.0", default-features = false }
# TODO(thane): Remove once https://github.com/rustwasm/wasm-bindgen/issues/2508 is resolved
syn = { version = "=1.0.65", default-features = false }
tendermint = { version = "0.23.0", default-features = false, path = "../tendermint" }
tendermint-light-client = { version = "0.23.0", default-features = false, path = "../light-client" }
tendermint-light-client-verifier = { version = "0.23.0", default-features = false, path = "../light-client-verifier" }
wasm-bindgen = { version = "0.2.63", default-features = false, features = [ "serde-serialize" ] }

# The `console_error_panic_hook` crate provides better debugging of panics by
Expand Down
10 changes: 5 additions & 5 deletions light-client-js/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
//! Tendermint Light Client JavaScript/WASM interface.
//!
//! This crate exposes some of the [`tendermint-light-client`] crate's
//! This crate exposes some of the [`tendermint-light-client-verifier`] crate's
//! functionality to be used from the JavaScript ecosystem.
//!
//! For a detailed example, please see the [`verifier-web` example] in the
//! repository.
//!
//! [`tendermint-light-client`]: https://github.com/informalsystems/tendermint-rs/tree/master/light-client
//! [`tendermint-light-client-verifier`]: https://github.com/informalsystems/tendermint-rs/tree/master/light-client-verifier
//! [`verifier-web` example]: https://github.com/informalsystems/tendermint-rs/tree/master/light-client-js/examples/verifier-web

mod utils;

use serde::{Deserialize, Serialize};
use std::time::Duration;
use tendermint::Time;
use tendermint_light_client::components::verifier::{ProdVerifier, Verifier};
use tendermint_light_client::light_client::Options;
use tendermint_light_client::types::{LightBlock, TrustThreshold};
use tendermint_light_client_verifier::options::Options;
use tendermint_light_client_verifier::types::{LightBlock, TrustThreshold};
use tendermint_light_client_verifier::{ProdVerifier, Verifier};
use wasm_bindgen::prelude::*;
use wasm_bindgen::JsValue;

Expand Down
4 changes: 2 additions & 2 deletions light-client-js/tests/web.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@

extern crate wasm_bindgen_test;
use tendermint::Time;
use tendermint_light_client::components::verifier::Verdict;
use tendermint_light_client::types::LightBlock;
use tendermint_light_client_js::{verify, Error, JsOptions};
use tendermint_light_client_verifier::types::LightBlock;
use tendermint_light_client_verifier::Verdict;
use wasm_bindgen::JsValue;
use wasm_bindgen_test::*;

Expand Down
38 changes: 38 additions & 0 deletions light-client-verifier/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
[package]
name = "tendermint-light-client-verifier"
version = "0.23.0"
edition = "2021"
license = "Apache-2.0"
readme = "README.md"
keywords = ["blockchain", "bft", "consensus", "cosmos", "tendermint"]
categories = ["cryptography::cryptocurrencies", "network-programming"]
repository = "https://github.com/informalsystems/tendermint-rs"
authors = [
"Informal Systems <[email protected]>",
]

description = """
Implementation of the Tendermint Light Client Verification Algorithm.
"""

# docs.rs-specific configuration
[package.metadata.docs.rs]
# document all features
all-features = true
# defines the configuration attribute `docsrs`
rustdoc-args = ["--cfg", "docsrs"]

[features]
default = ["flex-error/std", "flex-error/eyre_tracer"]

[dependencies]
tendermint = { version = "0.23.0", path = "../tendermint", default-features = false }
tendermint-rpc = { version = "0.23.0", path = "../rpc", default-features = false }

derive_more = { version = "0.99.5", default-features = false, features = ["display"] }
serde = { version = "1.0.106", default-features = false }
time = { version = "0.3.5", default-features = false }
flex-error = { version = "0.4.4", default-features = false }

[dev-dependencies]
tendermint-testgen = { path = "../testgen", default-features = false }
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
//! Errors which may be raised when verifying a `LightBlock`

use core::time::Duration;
use flex_error::define_error;
use serde::{Deserialize, Serialize};
use std::time::Duration;
use tendermint::account::Id;
use tendermint::Error as TendermintError;

use crate::errors::ErrorExt;
use crate::operations::voting_power::VotingPowerTally;
use crate::prelude::*;
use crate::types::{Hash, Height, Time, Validator, ValidatorAddress};
use tendermint::account::Id;
use tendermint::Error as TendermintError;

define_error! {
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
Expand All @@ -27,15 +27,6 @@ define_error! {
e.header_time, e.now)
},

ImplementationSpecific
{
detail: String,
}
| e | {
format_args!("implementation specific: {0}",
e.detail)
},

NotEnoughTrust
{
tally: VotingPowerTally,
Expand Down Expand Up @@ -171,6 +162,21 @@ define_error! {
}
}

/// Extension methods for `ErrorKind`
pub trait ErrorExt {
/// Whether this error means that the light block
/// cannot be trusted w.r.t. the latest trusted state.
fn not_enough_trust(&self) -> Option<VotingPowerTally>;

/// Whether this error means that the light block has expired,
/// ie. it's outside of the trusting period.
fn has_expired(&self) -> bool;

/// Whether this error means that a timeout occured when
/// querying a node.
fn is_timeout(&self) -> Option<Duration>;
}

impl ErrorExt for VerificationErrorDetail {
fn not_enough_trust(&self) -> Option<VotingPowerTally> {
match &self {
Expand Down
14 changes: 14 additions & 0 deletions light-client-verifier/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#![no_std]

extern crate alloc;

mod prelude;

pub mod errors;
pub mod operations;
pub mod options;
pub mod predicates;
pub mod types;
mod verifier;

pub use verifier::{PredicateVerifier, ProdVerifier, Verdict, Verifier};
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
//! Provides an interface and default implementation for the `CommitValidator` operation

use crate::{
errors::VerificationError,
operations::{Hasher, ProdHasher},
predicates::errors::VerificationError,
types::{SignedHeader, ValidatorSet},
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
//! Provides an interface and default implementation for the `VotingPower` operation

use crate::prelude::*;
use crate::{
predicates::errors::VerificationError,
errors::VerificationError,
types::{Commit, SignedHeader, TrustThreshold, ValidatorSet},
};

use alloc::collections::BTreeSet as HashSet;
use core::fmt;
use serde::{Deserialize, Serialize};
use std::collections::HashSet;
use std::fmt;

use std::convert::TryFrom;
use core::convert::TryFrom;
use tendermint::block::CommitSig;
use tendermint::trust_threshold::TrustThreshold as _;
use tendermint::vote::{SignedVote, ValidatorIndex, Vote};
Expand Down Expand Up @@ -220,7 +221,7 @@ fn non_absent_vote(
#[cfg(test)]
mod tests {
use super::*;
use crate::predicates::errors::VerificationErrorDetail;
use crate::errors::VerificationErrorDetail;
use crate::types::LightBlock;
use tendermint::trust_threshold::TrustThresholdFraction;
use tendermint_testgen::light_block::generate_signed_header;
Expand Down
30 changes: 30 additions & 0 deletions light-client-verifier/src/options.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//! Light client implementation as per the [Core Verification specification][1].
//!
//! [1]: https://github.com/informalsystems/tendermint-rs/blob/master/docs/spec/lightclient/verification/verification.md

use core::time::Duration;

use derive_more::Display;
use serde::{Deserialize, Serialize};

use crate::types::TrustThreshold;

/// Verification parameters
#[derive(Copy, Clone, Debug, PartialEq, Display, Serialize, Deserialize)]
#[display(fmt = "{:?}", self)]
pub struct Options {
/// Defines what fraction of the total voting power of a known
/// and trusted validator set is sufficient for a commit to be
/// accepted going forward.
pub trust_threshold: TrustThreshold,

/// How long a validator set is trusted for (must be shorter than the chain's
/// unbonding period)
pub trusting_period: Duration,

/// Correction parameter dealing with only approximately synchronized clocks.
/// The local clock should always be ahead of timestamps from the blockchain; this
/// is the maximum amount that the local clock may drift behind a timestamp from the
/// blockchain.
pub clock_drift: Duration,
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
//! Predicates for light block validation and verification.

use crate::errors::VerificationError;
use crate::prelude::*;
use crate::{
operations::{CommitValidator, Hasher, VotingPowerCalculator},
types::{Header, SignedHeader, Time, TrustThreshold, ValidatorSet},
};

use errors::VerificationError;
use std::time::Duration;
use core::time::Duration;
use tendermint::{block::Height, hash::Hash};

pub mod errors;

/// Production predicates, using the default implementation
/// of the `VerificationPredicates` trait.
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
Expand Down Expand Up @@ -205,8 +204,8 @@ pub trait VerificationPredicates: Send + Sync {

#[cfg(test)]
mod tests {
use std::convert::TryInto;
use std::time::Duration;
use core::convert::TryInto;
use core::time::Duration;
use tendermint::block::CommitSig;
use tendermint::validator::Set;
use time::OffsetDateTime;
Expand All @@ -216,9 +215,10 @@ mod tests {
Commit, Generator, Header, Validator, ValidatorSet,
};

use crate::predicates::{
use crate::prelude::*;
use crate::{
errors::{VerificationError, VerificationErrorDetail},
ProdPredicates, VerificationPredicates,
predicates::{ProdPredicates, VerificationPredicates},
};

use crate::operations::{
Expand Down
14 changes: 14 additions & 0 deletions light-client-verifier/src/prelude.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
pub use core::prelude::v1::*;

// Re-export according to alloc::prelude::v1 because it is not yet stabilized
// https://doc.rust-lang.org/src/alloc/prelude/v1.rs.html
pub use alloc::borrow::ToOwned;
pub use alloc::boxed::Box;
pub use alloc::string::{String, ToString};
pub use alloc::vec::Vec;

pub use alloc::format;
pub use alloc::vec;

// will be included in 2021 edition.
pub use core::convert::{TryFrom, TryInto};
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
//! Defines or just re-exports the main datatypes used by the light client.

use crate::prelude::*;

use derive_more::Display;
use serde::{Deserialize, Serialize};

Expand Down Expand Up @@ -73,7 +75,7 @@ impl Status {
///
/// From least to most trusted: `Failed`, `Unverified`, `Verified`, `Trusted`.
pub fn most_trusted(a: Self, b: Self) -> Self {
std::cmp::max(a, b)
core::cmp::max(a, b)
}
}

Expand Down Expand Up @@ -201,6 +203,7 @@ impl LatestStatus {
mod tests {

mod status {
use crate::prelude::*;
use crate::types::Status;
use Status::*;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,18 @@
//! Provides an interface and default implementation of the `Verifier` component

use crate::errors::{ErrorExt, VerificationError, VerificationErrorDetail};
use crate::operations::voting_power::VotingPowerTally;
use crate::predicates as preds;
use crate::types::{TrustedBlockState, UntrustedBlockState};
use crate::{
errors::ErrorExt,
light_client::Options,
operations::{
CommitValidator, Hasher, ProdCommitValidator, ProdHasher, ProdVotingPowerCalculator,
VotingPowerCalculator,
},
options::Options,
types::Time,
};
use preds::{
errors::{VerificationError, VerificationErrorDetail},
ProdPredicates, VerificationPredicates,
};
use preds::{ProdPredicates, VerificationPredicates};
use serde::{Deserialize, Serialize};

/// Represents the result of the verification performed by the
Expand Down
1 change: 1 addition & 0 deletions light-client/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ mbt = []
[dependencies]
tendermint = { version = "0.23.0", path = "../tendermint", default-features = false }
tendermint-rpc = { version = "0.23.0", path = "../rpc", default-features = false }
tendermint-light-client-verifier = { version = "0.23.0", path = "../light-client-verifier", default-features = false }

contracts = { version = "0.4.0", default-features = false }
crossbeam-channel = { version = "0.4.2", default-features = false }
Expand Down
9 changes: 4 additions & 5 deletions light-client/examples/light_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,14 @@ use std::{path::PathBuf, time::Duration};
use gumdrop::Options;

use tendermint::Hash;
use tendermint_rpc as rpc;

use tendermint_light_client::supervisor::{Handle as _, Instance};
use tendermint_light_client::verifier::options::Options as LightClientOptions;
use tendermint_light_client::verifier::types::{Height, PeerId, TrustThreshold};
use tendermint_light_client::{
builder::{LightClientBuilder, SupervisorBuilder},
light_client,
store::memory::MemoryStore,
types::{Height, PeerId, TrustThreshold},
};
use tendermint_rpc as rpc;

#[derive(Debug, Options)]
struct CliOptions {
Expand Down Expand Up @@ -82,7 +81,7 @@ fn make_instance(
) -> Result<Instance, Box<dyn std::error::Error>> {
let light_store = MemoryStore::new();
let rpc_client = rpc::HttpClient::new(addr).unwrap();
let options = light_client::Options {
let options = LightClientOptions {
trust_threshold: TrustThreshold::default(),
trusting_period: Duration::from_secs(36000),
clock_drift: Duration::from_secs(1),
Expand Down
2 changes: 1 addition & 1 deletion light-client/src/builder/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use tendermint::block::Height;
use tendermint::Hash;

use crate::components::io::IoError;
use crate::predicates::errors::VerificationError;
use crate::verifier::errors::VerificationError;

define_error! {
Error {
Expand Down
Loading