From 20c5ccf798331a0252cb24e36f8e9a1d07358e28 Mon Sep 17 00:00:00 2001 From: cezarad Date: Tue, 8 Jun 2021 07:59:37 +0200 Subject: [PATCH 01/32] bla --- modules/src/ics02_client/handler/update_client.rs | 10 +++++++++- modules/src/ics07_tendermint/client_def.rs | 12 ++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/modules/src/ics02_client/handler/update_client.rs b/modules/src/ics02_client/handler/update_client.rs index 25ef38f74e..0cc9ec79cc 100644 --- a/modules/src/ics02_client/handler/update_client.rs +++ b/modules/src/ics02_client/handler/update_client.rs @@ -4,11 +4,12 @@ use crate::events::IbcEvent; use crate::handler::{HandlerOutput, HandlerResult}; use crate::ics02_client::client_consensus::AnyConsensusState; use crate::ics02_client::client_def::{AnyClient, ClientDef}; -use crate::ics02_client::client_state::AnyClientState; +use crate::ics02_client::client_state::{AnyClientState, ClientState}; use crate::ics02_client::context::ClientReader; use crate::ics02_client::error::{Error, Kind}; use crate::ics02_client::events::Attributes; use crate::ics02_client::handler::ClientResult; +use crate::ics02_client::header::Header; use crate::ics02_client::msgs::update_client::MsgUpdateAnyClient; use crate::ics24_host::identifier::ClientId; @@ -45,10 +46,17 @@ pub fn process( .client_state(&client_id) .ok_or_else(|| Kind::ClientNotFound(client_id.clone()))?; + if client_state.is_frozen() { + return Err(Kind::ClientFrozen(client_id).into()); + } + let latest_height = client_state.latest_height(); ctx.consensus_state(&client_id, latest_height) .ok_or_else(|| Kind::ConsensusStateNotFound(client_id.clone(), latest_height))?; + if ctx.consensus_state(&client_id,header.height()).is_some(){ + return Err(Kind::ConsensusStateNotFound(client_id.clone(), latest_height).into()); + } // Use client_state to validate the new header against the latest consensus_state. // This function will return the new client_state (its latest_height changed) and a // consensus_state obtained from header. These will be later persisted by the keeper. diff --git a/modules/src/ics07_tendermint/client_def.rs b/modules/src/ics07_tendermint/client_def.rs index b6246c093b..aaeda5ff49 100644 --- a/modules/src/ics07_tendermint/client_def.rs +++ b/modules/src/ics07_tendermint/client_def.rs @@ -34,6 +34,18 @@ impl ClientDef for TendermintClient { ); } + if !client_state.frozen_height.is_zero(){ + return Err( + format!("client is frozen at height ({:?})", + client_state.frozen_height).into(), + ); + } + + + // if ctx.consensus_state(&client_id,header.height()).is_some(){ + // return Err(Kind::ConsensusStateNotFound(client_id.clone(), latest_height).into()); + // } + // TODO: Additional verifications should be implemented here. Ok(( From b5b9dcf5ea5b924ab2427de4ee980da6866677ef Mon Sep 17 00:00:00 2001 From: cezarad Date: Tue, 15 Jun 2021 10:50:41 +0200 Subject: [PATCH 02/32] on going --- modules/src/ics02_client/client_def.rs | 9 +++- .../src/ics02_client/handler/update_client.rs | 2 +- modules/src/ics07_tendermint/client_def.rs | 44 +++++++++++++++++-- modules/src/ics07_tendermint/client_state.rs | 8 ++++ modules/src/ics07_tendermint/header.rs | 16 +++++++ modules/src/mock/client_def.rs | 3 ++ 6 files changed, 76 insertions(+), 6 deletions(-) diff --git a/modules/src/ics02_client/client_def.rs b/modules/src/ics02_client/client_def.rs index 1ea12b75b5..f96a42419c 100644 --- a/modules/src/ics02_client/client_def.rs +++ b/modules/src/ics02_client/client_def.rs @@ -4,6 +4,7 @@ use crate::downcast; use crate::ics02_client::client_consensus::{AnyConsensusState, ConsensusState}; use crate::ics02_client::client_state::{AnyClientState, ClientState}; use crate::ics02_client::client_type::ClientType; +use crate::ics02_client::context::ClientReader; use crate::ics02_client::error::Kind; use crate::ics02_client::header::{AnyHeader, Header}; use crate::ics03_connection::connection::ConnectionEnd; @@ -25,6 +26,8 @@ pub trait ClientDef: Clone { /// TODO fn check_header_and_update_state( &self, + ctx: &dyn ClientReader, + client_id: ClientId, client_state: Self::ClientState, header: Self::Header, ) -> Result<(Self::ClientState, Self::ConsensusState), Box>; @@ -172,6 +175,8 @@ impl ClientDef for AnyClient { /// Validates an incoming `header` against the latest consensus state of this client. fn check_header_and_update_state( &self, + ctx: &dyn ClientReader, + client_id:ClientId, client_state: AnyClientState, header: AnyHeader, ) -> Result<(AnyClientState, AnyConsensusState), Box> { @@ -184,7 +189,7 @@ impl ClientDef for AnyClient { .ok_or_else(|| Kind::ClientArgsTypeMismatch(ClientType::Tendermint))?; let (new_state, new_consensus) = - client.check_header_and_update_state(client_state, header)?; + client.check_header_and_update_state(ctx, client_id, client_state, header)?; Ok(( AnyClientState::Tendermint(new_state), @@ -201,7 +206,7 @@ impl ClientDef for AnyClient { .ok_or_else(|| Kind::ClientArgsTypeMismatch(ClientType::Mock))?; let (new_state, new_consensus) = - client.check_header_and_update_state(client_state, header)?; + client.check_header_and_update_state(ctx, client_id, client_state, header)?; Ok(( AnyClientState::Mock(new_state), diff --git a/modules/src/ics02_client/handler/update_client.rs b/modules/src/ics02_client/handler/update_client.rs index 0cc9ec79cc..2315607cbb 100644 --- a/modules/src/ics02_client/handler/update_client.rs +++ b/modules/src/ics02_client/handler/update_client.rs @@ -61,7 +61,7 @@ pub fn process( // This function will return the new client_state (its latest_height changed) and a // consensus_state obtained from header. These will be later persisted by the keeper. let (new_client_state, new_consensus_state) = client_def - .check_header_and_update_state(client_state, header) + .check_header_and_update_state(ctx, client_id.clone(), client_state, header) .map_err(|e| Kind::HeaderVerificationFailure.context(e.to_string()))?; let result = ClientResult::Update(Result { diff --git a/modules/src/ics07_tendermint/client_def.rs b/modules/src/ics07_tendermint/client_def.rs index aaeda5ff49..0b7973764e 100644 --- a/modules/src/ics07_tendermint/client_def.rs +++ b/modules/src/ics07_tendermint/client_def.rs @@ -2,7 +2,10 @@ use ibc_proto::ibc::core::commitment::v1::MerkleProof; use crate::ics02_client::client_consensus::AnyConsensusState; use crate::ics02_client::client_def::ClientDef; +use crate::ics02_client::error::Kind; use crate::ics02_client::client_state::AnyClientState; +use crate::ics02_client::context::ClientReader; +use crate::ics02_client::client_type::ClientType; use crate::ics03_connection::connection::ConnectionEnd; use crate::ics04_channel::channel::ChannelEnd; use crate::ics04_channel::packet::Sequence; @@ -14,6 +17,9 @@ use crate::ics24_host::identifier::ConnectionId; use crate::ics24_host::identifier::{ChannelId, ClientId, PortId}; use crate::Height; +use crate::downcast; + + #[derive(Clone, Debug, PartialEq, Eq)] pub struct TendermintClient; @@ -24,6 +30,8 @@ impl ClientDef for TendermintClient { fn check_header_and_update_state( &self, + ctx: &dyn ClientReader, + client_id: ClientId, client_state: Self::ClientState, header: Self::Header, ) -> Result<(Self::ClientState, Self::ConsensusState), Box> { @@ -41,10 +49,39 @@ impl ClientDef for TendermintClient { ); } + match ctx.consensus_state(&client_id, header.height()){ + //could the header height be zero ? + Some(cs) => { + let consensus_state = downcast!( + cs => AnyConsensusState::Tendermint + ).ok_or_else(|| Kind::ClientArgsTypeMismatch(ClientType::Tendermint))?; + + if consensus_state != ConsensusState::from(header.clone()){ + //freeze the client and return the installed consensus state + return Ok((client_state.with_set_frozen(header.height()), + consensus_state)) + } + } + None =>{} + } + + let _trusted_consensus_state = + match ctx.consensus_state(&client_id, header.trusted_height) { + Some(ts) => { + downcast!( + ts => AnyConsensusState::Tendermint + ).ok_or_else(|| Kind::ClientArgsTypeMismatch(ClientType::Tendermint))? + } + None => { + return Err( + format!("Missing consensus state for the client {} at trusted height {:?}", + client_id, + header.trusted_height).into(), + ) + } + }; + - // if ctx.consensus_state(&client_id,header.height()).is_some(){ - // return Err(Kind::ConsensusStateNotFound(client_id.clone(), latest_height).into()); - // } // TODO: Additional verifications should be implemented here. @@ -54,6 +91,7 @@ impl ClientDef for TendermintClient { )) } + fn verify_client_consensus_state( &self, _client_state: &Self::ClientState, diff --git a/modules/src/ics07_tendermint/client_state.rs b/modules/src/ics07_tendermint/client_state.rs index d389525f8f..6ef376b9f8 100644 --- a/modules/src/ics07_tendermint/client_state.rs +++ b/modules/src/ics07_tendermint/client_state.rs @@ -111,6 +111,14 @@ impl ClientState { } } + + pub fn with_set_frozen(self, h: Height) -> Self { + ClientState { + frozen_height: h, + ..self + } + } + /// Helper function to verify the upgrade client procedure. /// Resets all fields except the blockchain-specific ones. pub fn zero_custom_fields(mut client_state: Self) -> Self { diff --git a/modules/src/ics07_tendermint/header.rs b/modules/src/ics07_tendermint/header.rs index d6ec0d80c3..4230626bf8 100644 --- a/modules/src/ics07_tendermint/header.rs +++ b/modules/src/ics07_tendermint/header.rs @@ -60,6 +60,22 @@ impl Header { } } } + + // pub fn header_equality(&self, other_header: &Header) -> bool{ + // let other_height = other_header.signed_header.header.height; + // let self_height = self.signed_header.header.height; + // //TODO we need signed header eq + // if self.signed_header.header != other_header.signed_header.header + // return false; + // } + + // if self.signed_header.commit != other_header.signed_header.commit + // return false; + // } + // if self.validator_set != other_header.validator_set + + + // } } impl crate::ics02_client::header::Header for Header { diff --git a/modules/src/mock/client_def.rs b/modules/src/mock/client_def.rs index db33791946..c030fbf22b 100644 --- a/modules/src/mock/client_def.rs +++ b/modules/src/mock/client_def.rs @@ -3,6 +3,7 @@ use ibc_proto::ibc::core::commitment::v1::MerkleProof; use crate::ics02_client::client_consensus::AnyConsensusState; use crate::ics02_client::client_def::ClientDef; use crate::ics02_client::client_state::AnyClientState; +use crate::ics02_client::context::ClientReader; use crate::ics03_connection::connection::ConnectionEnd; use crate::ics04_channel::channel::ChannelEnd; use crate::ics04_channel::packet::Sequence; @@ -24,6 +25,8 @@ impl ClientDef for MockClient { fn check_header_and_update_state( &self, + _ctx: &dyn ClientReader, + _client_id: ClientId, client_state: Self::ClientState, header: Self::Header, ) -> Result<(Self::ClientState, Self::ConsensusState), Box> { From dae68b10c3577aaea747a21c0a296b75551788f2 Mon Sep 17 00:00:00 2001 From: cezarad Date: Thu, 17 Jun 2021 08:07:04 +0200 Subject: [PATCH 03/32] ongoing --- .../src/ics02_client/handler/update_client.rs | 2 +- modules/src/ics07_tendermint/client_def.rs | 100 +++++++++++++++++- 2 files changed, 100 insertions(+), 2 deletions(-) diff --git a/modules/src/ics02_client/handler/update_client.rs b/modules/src/ics02_client/handler/update_client.rs index 2315607cbb..f152abc86f 100644 --- a/modules/src/ics02_client/handler/update_client.rs +++ b/modules/src/ics02_client/handler/update_client.rs @@ -54,7 +54,7 @@ pub fn process( ctx.consensus_state(&client_id, latest_height) .ok_or_else(|| Kind::ConsensusStateNotFound(client_id.clone(), latest_height))?; - if ctx.consensus_state(&client_id,header.height()).is_some(){ + if ctx.consensus_state(&client_id, header.height()).is_some(){ return Err(Kind::ConsensusStateNotFound(client_id.clone(), latest_height).into()); } // Use client_state to validate the new header against the latest consensus_state. diff --git a/modules/src/ics07_tendermint/client_def.rs b/modules/src/ics07_tendermint/client_def.rs index 0b7973764e..e12c9e8d98 100644 --- a/modules/src/ics07_tendermint/client_def.rs +++ b/modules/src/ics07_tendermint/client_def.rs @@ -16,6 +16,9 @@ use crate::ics23_commitment::commitment::{CommitmentPrefix, CommitmentProofBytes use crate::ics24_host::identifier::ConnectionId; use crate::ics24_host::identifier::{ChannelId, ClientId, PortId}; use crate::Height; +use std::ops::Sub; +use tendermint::Time; +use tendermint::validator::Set; use crate::downcast; @@ -49,6 +52,9 @@ impl ClientDef for TendermintClient { ); } + // check if a consensus state is already installed; if so it should + // match the untrusted header. + match ctx.consensus_state(&client_id, header.height()){ //could the header height be zero ? Some(cs) => { @@ -65,7 +71,81 @@ impl ClientDef for TendermintClient { None =>{} } - let _trusted_consensus_state = + let latest_consensus_state = match ctx.consensus_state(&client_id, client_state.latest_height){ + //could the header height be zero ? + Some(cs) => { + downcast!( + cs => AnyConsensusState::Tendermint + ).ok_or_else(|| Kind::ClientArgsTypeMismatch(ClientType::Tendermint))? + } + None =>{ + return Err( + format!("no consensus_state for client height {}", + client_state.latest_height).into(), + ); + } + }; + + + // check that the header is not outside the trusting period + if header.signed_header.header().time.sub(client_state.trusting_period) >= latest_consensus_state.timestamp { + return Err( + format!("header outside of the trusting period {:?}, {:?}", + latest_consensus_state.timestamp, + header.signed_header.header().time).into(), + ); + }; + + // check that the client did not expired + if Time::now().sub(client_state.trusting_period) >= latest_consensus_state.timestamp { + return Err( + format!("consensus state expired; it's outside of the trusting period {:?}, {:?}", + latest_consensus_state.timestamp, + Time::now()).into(), + ); + }; + + // check monotonicity of height and timestamp + if client_state.latest_height >= header.height() { + return Err( + format!("non monotonic height update {}, {:?}", + client_state.latest_height, + header.height()).into(), + ); + }; + + // check monotonicity of header height vs trusted height. + // unclear needed + if header.trusted_height >= header.height() { + return Err( + format!("non monotonic height update w.r.t trusted header {}, {:?}", + header.trusted_height, + header.height()).into(), + ); + }; + + // check that the versions of the client state and the header match + if client_state.latest_height.revision_number != header.height().revision_number { + return Err( + format!("client revision number {} does not match the header's revision number {}", + client_state.latest_height.revision_number, + header.height().revision_number).into(), + ); + }; + + if latest_consensus_state.timestamp >= header.signed_header.header().time { + //TODO add clock drift ? + return Err( + format!("non monotonic timestamps update {}, {:?}", + client_state.latest_height, + header.height()).into(), + ); + }; + + + + + let trusted_consensus_state = match ctx.consensus_state(&client_id, header.trusted_height) { Some(ts) => { downcast!( @@ -80,8 +160,26 @@ impl ClientDef for TendermintClient { ) } }; + + // check that the header's trusted validator set is + // the next_validator_set of the trusted consensus state + if Set::hash(&header.validator_set) != trusted_consensus_state.next_validators_hash { + return Err( + format!( + // "ErrInvalidValidatorSet, + "the headers trusted validators do not hash to next val set of the trusted consensus state. Expected: {:?}, got: {:?}", + trusted_consensus_state.next_validators_hash, Set::hash(&header.validator_set) + ).into(), + ) + } + if header.height() == header.trusted_height.increment() { + //adjacent + + }else{ + //Non-adjacent + } // TODO: Additional verifications should be implemented here. From 1b4ac9fed26a82548a082853b3a6b97db4fc7915 Mon Sep 17 00:00:00 2001 From: cezarad Date: Fri, 18 Jun 2021 11:12:10 +0200 Subject: [PATCH 04/32] on going --- modules/src/ics02_client/error.rs | 19 +++ modules/src/ics07_tendermint/client_def.rs | 53 +++++-- modules/src/ics07_tendermint/error.rs | 26 ++++ modules/src/ics07_tendermint/mod.rs | 1 + modules/src/ics07_tendermint/predicates.rs | 161 +++++++++++++++++++++ 5 files changed, 248 insertions(+), 12 deletions(-) create mode 100644 modules/src/ics07_tendermint/predicates.rs diff --git a/modules/src/ics02_client/error.rs b/modules/src/ics02_client/error.rs index a462689a28..9061292e89 100644 --- a/modules/src/ics02_client/error.rs +++ b/modules/src/ics02_client/error.rs @@ -111,6 +111,25 @@ pub enum Kind { #[error("upgraded client height {0} must be at greater than current client height {1}")] LowUpgradeHeight(Height, Height), + + /// Insufficient voting power in the commit + #[error("insufficient overlap {0}")] + InsufficientVotingPower(String), + + /// Not enough trust because insufficient validators overlap + #[error("not enough trust because insufficient validators overlap: {0}")] + NotEnoughTrustedValsSigned(String), + + /// Hash mismatch for the validator set + #[error("invalid validator set: header_validators_hash={header_validators_hash} validators_hash={validators_hash}")] + InvalidValidatorSet { + /// Hash of validator set stored in header + #[serde(with = "tendermint::serializers::hash")] + header_validators_hash: Hash, + /// Actual hash of validator set in header + #[serde(with = "tendermint::serializers::hash")] + validators_hash: Hash, + }, } impl Kind { diff --git a/modules/src/ics07_tendermint/client_def.rs b/modules/src/ics07_tendermint/client_def.rs index e12c9e8d98..6e1038bcb3 100644 --- a/modules/src/ics07_tendermint/client_def.rs +++ b/modules/src/ics07_tendermint/client_def.rs @@ -12,6 +12,8 @@ use crate::ics04_channel::packet::Sequence; use crate::ics07_tendermint::client_state::ClientState; use crate::ics07_tendermint::consensus_state::ConsensusState; use crate::ics07_tendermint::header::Header; +use crate::ics07_tendermint::predicates::Predicates; + use crate::ics23_commitment::commitment::{CommitmentPrefix, CommitmentProofBytes, CommitmentRoot}; use crate::ics24_host::identifier::ConnectionId; use crate::ics24_host::identifier::{ChannelId, ClientId, PortId}; @@ -19,6 +21,7 @@ use crate::Height; use std::ops::Sub; use tendermint::Time; use tendermint::validator::Set; +use tendermint::trust_threshold::TrustThresholdFraction; use crate::downcast; @@ -161,24 +164,50 @@ impl ClientDef for TendermintClient { } }; - // check that the header's trusted validator set is - // the next_validator_set of the trusted consensus state - if Set::hash(&header.validator_set) != trusted_consensus_state.next_validators_hash { - return Err( - format!( - // "ErrInvalidValidatorSet, - "the headers trusted validators do not hash to next val set of the trusted consensus state. Expected: {:?}, got: {:?}", - trusted_consensus_state.next_validators_hash, Set::hash(&header.validator_set) - ).into(), - ) - } if header.height() == header.trusted_height.increment() { //adjacent - + + // check that the header's trusted validator set is + // the next_validator_set of the trusted consensus state + if Set::hash(&header.validator_set) != trusted_consensus_state.next_validators_hash { + return Err( + format!( + // "ErrInvalidValidatorSet, + "the headers trusted validators do not hash to next val set of the trusted consensus state. Expected: {:?}, got: {:?}", + trusted_consensus_state.next_validators_hash, Set::hash(&header.validator_set) + ).into(), + ) + } + let pred = Predicates::default(); + + // check that the validators that sign the commit of the untrusted header + // have 2/3 of the voting power of the current validator set. + match pred.voting_power_in(&header.signed_header,&header.validator_set,TrustThresholdFraction::TWO_THIRDS){ + Err(e) => { return Err(Kind::InsufficientVotingPower(e.to_string()).into()); } + _ =>{} + }; + + + }else{ //Non-adjacent + let pred = Predicates::default(); + + //check that a subset of the trusted validator set, having 1/3 of the voting power + //signes the commit of the untrusted header + match pred.voting_power_in(&header.signed_header,&header.trusted_validator_set,TrustThresholdFraction::default()){ + Err(e) => { return Err(Kind::NotEnoughTrustedValsSigned(e.to_string()).into());} + _ => {} + }; + + // check that the validators that sign the commit of the untrusted header + // have 2/3 of the voting power of the current validator set. + match pred.voting_power_in(&header.signed_header,&header.validator_set,TrustThresholdFraction::TWO_THIRDS){ + Err(e) => { return Err(Kind::InsufficientVotingPower(e.to_string()).into()); } + _ =>{} + }; } // TODO: Additional verifications should be implemented here. diff --git a/modules/src/ics07_tendermint/error.rs b/modules/src/ics07_tendermint/error.rs index 482c4f4ae2..0035b12974 100644 --- a/modules/src/ics07_tendermint/error.rs +++ b/modules/src/ics07_tendermint/error.rs @@ -2,6 +2,8 @@ use anomaly::{BoxError, Context}; use thiserror::Error; use crate::ics24_host::error::ValidationKind; +use tendermint::{validator::Info, + account::Id}; pub type Error = anomaly::Error; @@ -46,3 +48,27 @@ impl Kind { Context::new(self, Some(source.into())) } } + +#[derive(Clone, Debug, Error)] +pub enum VerificationError{ + #[error("Couldn't verify signature `{signature:?}` with validator `{validator:?}` on sign_bytes `{sign_bytes:?}`")] + InvalidSignature { + /// Signature as a byte array + signature: Vec, + /// Validator which provided the signature + validator: Box, + /// Bytes which were signed + sign_bytes: Vec, + }, + + /// Duplicate validator in commit signatures + #[error("duplicate validator with address {0}")] + DuplicateValidator(Id), + + /// Insufficient signers overlap + #[error("insufficient signers overlap {0} {1}")] + InsufficientOverlap(u64, u64), + + + +} diff --git a/modules/src/ics07_tendermint/mod.rs b/modules/src/ics07_tendermint/mod.rs index 0c4263997f..5be0aad568 100644 --- a/modules/src/ics07_tendermint/mod.rs +++ b/modules/src/ics07_tendermint/mod.rs @@ -6,3 +6,4 @@ pub mod consensus_state; pub mod error; pub mod header; pub mod misbehaviour; +pub mod predicates; \ No newline at end of file diff --git a/modules/src/ics07_tendermint/predicates.rs b/modules/src/ics07_tendermint/predicates.rs new file mode 100644 index 0000000000..6a1b949cb4 --- /dev/null +++ b/modules/src/ics07_tendermint/predicates.rs @@ -0,0 +1,161 @@ +use tendermint::block::signed_header::SignedHeader; +use tendermint::validator::Set as ValidatorSet; +use tendermint::trust_threshold::TrustThresholdFraction; +use tendermint::trust_threshold::TrustThreshold; +use tendermint::block::{CommitSig,Commit}; +use tendermint::vote::{SignedVote,ValidatorIndex,Vote}; +use std::collections::HashSet; +use std::convert::TryFrom; +use crate::ics07_tendermint::error::VerificationError; + + +// pub struct VotingPowerTally { +// /// Total voting power +// pub total: u64, +// /// Tallied voting power +// pub tallied: u64, +// /// Trust threshold for voting power +// pub trust_threshold: TrustThresholdFraction, +// } + +#[derive(Copy, Clone, Debug, Default)] +pub struct Predicates; + +impl Predicates +{ + + /// Compute the voting power in a header and its commit against a validator set. + /// + /// The `trust_threshold` is currently not used, but might be in the future + /// for optimization purposes. + pub fn voting_power_in( + &self, + signed_header: &SignedHeader, + validator_set: &ValidatorSet, + trust_threshold: TrustThresholdFraction, + ) -> Result<(), Box> { + + let signatures = &signed_header.commit.signatures; + + let mut tallied_voting_power = 0_u64; + let mut seen_validators = HashSet::new(); + + // Get non-absent votes from the signatures + let non_absent_votes = signatures.iter().enumerate().flat_map(|(idx, signature)| { + non_absent_vote( + signature, + ValidatorIndex::try_from(idx).unwrap(), + &signed_header.commit, + ) + .map(|vote| (signature, vote)) + }); + + let total_voting_power = self.total_power_of(validator_set); + + for (signature, vote) in non_absent_votes { + // Ensure we only count a validator's power once + if seen_validators.contains(&vote.validator_address) { + return Err(VerificationError::DuplicateValidator( + vote.validator_address + ).into()); + } else { + seen_validators.insert(vote.validator_address); + } + + let validator = match validator_set.validator(vote.validator_address) { + Some(validator) => validator, + None => continue, // Cannot find matching validator, so we skip the vote + }; + + let signed_vote = SignedVote::new( + vote.clone(), + signed_header.header.chain_id.clone(), + vote.validator_address, + vote.signature, + ); + + // Check vote is valid + let sign_bytes = signed_vote.sign_bytes(); + if validator + .verify_signature(&sign_bytes, signed_vote.signature()) + .is_err() + { + return Err((VerificationError::InvalidSignature{ + signature: signed_vote.signature().to_bytes(), + validator: Box::new(validator), + sign_bytes}).into()); + } + + // If the vote is neither absent nor nil, tally its power + if signature.is_commit() { + tallied_voting_power += validator.power(); + if trust_threshold.is_enough_power(tallied_voting_power,total_voting_power) { + return Ok(()) + } + } else { + // It's OK. We include stray signatures (~votes for nil) + // to measure validator availability. + } + } + + return Err(VerificationError::InsufficientOverlap(tallied_voting_power,total_voting_power).into()); + + // let voting_power = VotingPowerTally { + // total: self.total_power_of(validator_set), + // tallied: tallied_voting_power, + // trust_threshold, + // }; + + // if !trust_threshold.is_enough_power(voting_power.tallied,voting_power.total){ + // return Err(format!("bla").into()); + // } + + // Ok(()) + } + + /// Compute the total voting power in a validator set + fn total_power_of(&self, validator_set: &ValidatorSet) -> u64 { + validator_set + .validators() + .iter() + .fold(0u64, |total, val_info| { + total + val_info.voting_power.value() + }) + } +} + +fn non_absent_vote( + commit_sig: &CommitSig, + validator_index: ValidatorIndex, + commit: &Commit, +) -> Option { + let (validator_address, timestamp, signature, block_id) = match commit_sig { + CommitSig::BlockIdFlagAbsent { .. } => return None, + CommitSig::BlockIdFlagCommit { + validator_address, + timestamp, + signature, + } => ( + *validator_address, + *timestamp, + signature, + Some(commit.block_id), + ), + CommitSig::BlockIdFlagNil { + validator_address, + timestamp, + signature, + } => (*validator_address, *timestamp, signature, None), + }; + + Some(Vote { + vote_type: tendermint::vote::Type::Precommit, + height: commit.height, + round: commit.round, + block_id, + timestamp: Some(timestamp), + validator_address, + validator_index, + signature: *signature, + }) +} \ No newline at end of file From 58b5618520e8b72a7c8cc0ba55704b1d53f42c26 Mon Sep 17 00:00:00 2001 From: cezarad Date: Sat, 19 Jun 2021 20:53:04 +0200 Subject: [PATCH 05/32] on going --- modules/src/ics02_client/error.rs | 26 ++++++--- .../src/ics02_client/handler/update_client.rs | 20 +++++-- modules/src/ics07_tendermint/client_def.rs | 56 +++++++++++-------- 3 files changed, 63 insertions(+), 39 deletions(-) diff --git a/modules/src/ics02_client/error.rs b/modules/src/ics02_client/error.rs index 9061292e89..aa82f3e292 100644 --- a/modules/src/ics02_client/error.rs +++ b/modules/src/ics02_client/error.rs @@ -8,6 +8,8 @@ use crate::ics23_commitment::error::Error as Ics23Error; use crate::ics24_host::error::ValidationKind; use crate::ics24_host::identifier::ClientId; use crate::Height; +use crate::timestamp::Timestamp; +use tendermint::hash::Hash; pub type Error = anomaly::Error; @@ -121,15 +123,21 @@ pub enum Kind { NotEnoughTrustedValsSigned(String), /// Hash mismatch for the validator set - #[error("invalid validator set: header_validators_hash={header_validators_hash} validators_hash={validators_hash}")] - InvalidValidatorSet { - /// Hash of validator set stored in header - #[serde(with = "tendermint::serializers::hash")] - header_validators_hash: Hash, - /// Actual hash of validator set in header - #[serde(with = "tendermint::serializers::hash")] - validators_hash: Hash, - }, + #[error("invalid validator set: header_validators_hash={0} validators_hash={1}")] + InvalidValidatorSet(Hash, Hash), + + #[error("not withing trusting period: expires_at={0} now={1}")] + ClientStateNotWithinTrustPeriod (Timestamp,Timestamp), + + #[error("Consensus state timestamp {0} undefined or ahead of now time {1}")] + InvalidConsensusStateTimestamp(Timestamp,Timestamp), + + + #[error(" hearder height {0} must be at greater than current client height {1}")] + LowUpdateHeight(Height, Height), + + #[error(" hearder height = {0} is invalid")] + InvalidHeaderHeight(Height), } impl Kind { diff --git a/modules/src/ics02_client/handler/update_client.rs b/modules/src/ics02_client/handler/update_client.rs index f152abc86f..e25c569cb2 100644 --- a/modules/src/ics02_client/handler/update_client.rs +++ b/modules/src/ics02_client/handler/update_client.rs @@ -9,9 +9,10 @@ use crate::ics02_client::context::ClientReader; use crate::ics02_client::error::{Error, Kind}; use crate::ics02_client::events::Attributes; use crate::ics02_client::handler::ClientResult; -use crate::ics02_client::header::Header; +//use crate::ics02_client::header::Header; use crate::ics02_client::msgs::update_client::MsgUpdateAnyClient; use crate::ics24_host::identifier::ClientId; +use crate::timestamp::Timestamp; /// The result following the successful processing of a `MsgUpdateAnyClient` message. Preferably /// this data type should be used with a qualified name `update_client::Result` to avoid ambiguity. @@ -50,13 +51,20 @@ pub fn process( return Err(Kind::ClientFrozen(client_id).into()); } - let latest_height = client_state.latest_height(); - ctx.consensus_state(&client_id, latest_height) - .ok_or_else(|| Kind::ConsensusStateNotFound(client_id.clone(), latest_height))?; + // Read consensus state from the host chain store. + let latest_consensus_state = ctx.consensus_state(&client_id, client_state.latest_height()) + .ok_or_else(|| Kind::ConsensusStateNotFound(client_id.clone(), client_state.latest_height()))?; - if ctx.consensus_state(&client_id, header.height()).is_some(){ - return Err(Kind::ConsensusStateNotFound(client_id.clone(), latest_height).into()); + let duration = + Timestamp::now().duration_since(&latest_consensus_state.timestamp()) + .ok_or_else(|| Kind::InvalidConsensusStateTimestamp(latest_consensus_state.timestamp(),Timestamp::now()))?; + + if client_state.expired(duration){ + return Err(Kind::ClientStateNotWithinTrustPeriod(latest_consensus_state.timestamp(),Timestamp::now()).into()); } + + + // Use client_state to validate the new header against the latest consensus_state. // This function will return the new client_state (its latest_height changed) and a // consensus_state obtained from header. These will be later persisted by the keeper. diff --git a/modules/src/ics07_tendermint/client_def.rs b/modules/src/ics07_tendermint/client_def.rs index 6e1038bcb3..937b00f47a 100644 --- a/modules/src/ics07_tendermint/client_def.rs +++ b/modules/src/ics07_tendermint/client_def.rs @@ -19,9 +19,9 @@ use crate::ics24_host::identifier::ConnectionId; use crate::ics24_host::identifier::{ChannelId, ClientId, PortId}; use crate::Height; use std::ops::Sub; -use tendermint::Time; use tendermint::validator::Set; use tendermint::trust_threshold::TrustThresholdFraction; +//use tendermint::Time; use crate::downcast; @@ -41,23 +41,41 @@ impl ClientDef for TendermintClient { client_state: Self::ClientState, header: Self::Header, ) -> Result<(Self::ClientState, Self::ConsensusState), Box> { + + + + + // DONE in HANDLER + // if !client_state.frozen_height.is_zero(){ + // return Err( + // format!("client is frozen at height ({:?})", + // client_state.frozen_height).into(), + // ); + // } + + // // check that the client did not expired + // if Time::now().sub(client_state.trusting_period) >= latest_consensus_state.timestamp { + // return Err( + // format!("consensus state expired; it's outside of the trusting period {:?}, {:?}", + // latest_consensus_state.timestamp, + // Time::now()).into(), + // ); + // }; + + if client_state.latest_height() >= header.height() { - return Err( - format!("received header height ({:?}) is lower than (or equal to) client latest height ({:?})", + return Err(Kind::LowUpdateHeight( header.height(), client_state.latest_height).into(), ); } - if !client_state.frozen_height.is_zero(){ - return Err( - format!("client is frozen at height ({:?})", - client_state.frozen_height).into(), - ); + if header.height().is_zero() { + return Err(Kind::InvalidHeaderHeight(header.height()).into()); } + // check if a consensus state is already installed; if so it should // match the untrusted header. - match ctx.consensus_state(&client_id, header.height()){ //could the header height be zero ? Some(cs) => { @@ -83,7 +101,7 @@ impl ClientDef for TendermintClient { } None =>{ return Err( - format!("no consensus_state for client height {}", + Kind::ConsensusStateNotFound(client_id.clone(), client_state.latest_height).into(), ); } @@ -99,15 +117,7 @@ impl ClientDef for TendermintClient { ); }; - // check that the client did not expired - if Time::now().sub(client_state.trusting_period) >= latest_consensus_state.timestamp { - return Err( - format!("consensus state expired; it's outside of the trusting period {:?}, {:?}", - latest_consensus_state.timestamp, - Time::now()).into(), - ); - }; - + // check monotonicity of height and timestamp if client_state.latest_height >= header.height() { return Err( @@ -172,11 +182,9 @@ impl ClientDef for TendermintClient { // check that the header's trusted validator set is // the next_validator_set of the trusted consensus state if Set::hash(&header.validator_set) != trusted_consensus_state.next_validators_hash { - return Err( - format!( - // "ErrInvalidValidatorSet, - "the headers trusted validators do not hash to next val set of the trusted consensus state. Expected: {:?}, got: {:?}", - trusted_consensus_state.next_validators_hash, Set::hash(&header.validator_set) + return Err(Kind::InvalidValidatorSet( + trusted_consensus_state.next_validators_hash, + Set::hash(&header.validator_set) ).into(), ) } From 4fb5a0d4bb95054830a3a6fe422b72fb19aa1ced Mon Sep 17 00:00:00 2001 From: cezarad Date: Sat, 19 Jun 2021 23:04:02 +0200 Subject: [PATCH 06/32] timestamp default changed from none to now --- modules/src/ics02_client/error.rs | 21 +++++++-- .../src/ics02_client/handler/update_client.rs | 13 ++++-- .../src/ics04_channel/handler/send_packet.rs | 7 ++- modules/src/ics07_tendermint/client_def.rs | 43 +++++++++---------- modules/src/mock/header.rs | 8 +++- 5 files changed, 61 insertions(+), 31 deletions(-) diff --git a/modules/src/ics02_client/error.rs b/modules/src/ics02_client/error.rs index aa82f3e292..e146770b5b 100644 --- a/modules/src/ics02_client/error.rs +++ b/modules/src/ics02_client/error.rs @@ -118,24 +118,39 @@ pub enum Kind { #[error("insufficient overlap {0}")] InsufficientVotingPower(String), + #[error("Timestamp none or {0} and now {1}")] + InvalidConsensusStateTimestamp(Timestamp,Timestamp), + /// Not enough trust because insufficient validators overlap #[error("not enough trust because insufficient validators overlap: {0}")] NotEnoughTrustedValsSigned(String), - /// Hash mismatch for the validator set + /// Hash mismatch for the validator set #[error("invalid validator set: header_validators_hash={0} validators_hash={1}")] InvalidValidatorSet(Hash, Hash), #[error("not withing trusting period: expires_at={0} now={1}")] ClientStateNotWithinTrustPeriod (Timestamp,Timestamp), - #[error("Consensus state timestamp {0} undefined or ahead of now time {1}")] - InvalidConsensusStateTimestamp(Timestamp,Timestamp), + #[error("header not withing trusting period: expires_at={0} now={1}")] + HeaderNotWithinTrustPeriod (Timestamp,Timestamp), + + #[error("Header timestamp {0} is outside the trusting period w.r.t. consenus state timestamp{1}")] + HeaderTimestampOutsideTrustingTime(String,String), + #[error("Header revision {0} and client state revision {1} should coincide")] + MismatchedRevisions(u64,u64), #[error(" hearder height {0} must be at greater than current client height {1}")] LowUpdateHeight(Height, Height), + // #[error(" hearder timestamp {0} must be at greater than current client consensus state timestamp {1}")] + // LowUpdateTimestamp(Timestamp, Timestamp), + + + #[error(" hearder timestamp {0} must be at greater than current client consensus state timestamp {1}")] + LowUpdateTimestamp(String, String), + #[error(" hearder height = {0} is invalid")] InvalidHeaderHeight(Height), } diff --git a/modules/src/ics02_client/handler/update_client.rs b/modules/src/ics02_client/handler/update_client.rs index e25c569cb2..8fc22535cb 100644 --- a/modules/src/ics02_client/handler/update_client.rs +++ b/modules/src/ics02_client/handler/update_client.rs @@ -14,6 +14,8 @@ use crate::ics02_client::msgs::update_client::MsgUpdateAnyClient; use crate::ics24_host::identifier::ClientId; use crate::timestamp::Timestamp; +use tracing::info; + /// The result following the successful processing of a `MsgUpdateAnyClient` message. Preferably /// this data type should be used with a qualified name `update_client::Result` to avoid ambiguity. #[derive(Clone, Debug, PartialEq, Eq)] @@ -55,6 +57,8 @@ pub fn process( let latest_consensus_state = ctx.consensus_state(&client_id, client_state.latest_height()) .ok_or_else(|| Kind::ConsensusStateNotFound(client_id.clone(), client_state.latest_height()))?; + info!("latest conseus state {:?}", latest_consensus_state); + let duration = Timestamp::now().duration_since(&latest_consensus_state.timestamp()) .ok_or_else(|| Kind::InvalidConsensusStateTimestamp(latest_consensus_state.timestamp(),Timestamp::now()))?; @@ -107,16 +111,19 @@ mod tests { use crate::mock::header::MockHeader; use crate::test_utils::get_dummy_account_id; use crate::Height; + use crate::timestamp::Timestamp; #[test] fn test_update_client_ok() { let client_id = ClientId::default(); let signer = get_dummy_account_id(); + let timestamp = Timestamp::now(); + let ctx = MockContext::default().with_client(&client_id, Height::new(0, 42)); let msg = MsgUpdateAnyClient { client_id: client_id.clone(), - header: MockHeader::new(Height::new(0, 46)).into(), + header: MockHeader::new_time(Height::new(0, 46), timestamp).into(), signer, }; @@ -140,8 +147,8 @@ mod tests { assert_eq!(upd_res.client_id, client_id); assert_eq!( upd_res.client_state, - AnyClientState::Mock(MockClientState(MockHeader::new( - msg.header.height() + AnyClientState::Mock(MockClientState(MockHeader::new_time( + msg.header.height(),timestamp ))) ) } diff --git a/modules/src/ics04_channel/handler/send_packet.rs b/modules/src/ics04_channel/handler/send_packet.rs index 983ba90aa5..34ac984344 100644 --- a/modules/src/ics04_channel/handler/send_packet.rs +++ b/modules/src/ics04_channel/handler/send_packet.rs @@ -132,6 +132,9 @@ mod tests { use crate::ics24_host::identifier::{ChannelId, ClientId, ConnectionId, PortId}; use crate::mock::context::MockContext; use crate::timestamp::ZERO_DURATION; + use crate::timestamp::Timestamp; + use std::time::Duration; + use std::ops::Add; #[test] fn send_packet_processing() { @@ -144,7 +147,9 @@ mod tests { let context = MockContext::default(); - let mut packet: Packet = get_dummy_raw_packet(1, 6).try_into().unwrap(); + let timestamp = Timestamp::now().add(Duration::from_secs(10)); + + let mut packet: Packet = get_dummy_raw_packet(1, timestamp.unwrap().as_nanoseconds()).try_into().unwrap(); packet.sequence = 1.into(); packet.data = vec![0]; diff --git a/modules/src/ics07_tendermint/client_def.rs b/modules/src/ics07_tendermint/client_def.rs index 937b00f47a..492bfbbabc 100644 --- a/modules/src/ics07_tendermint/client_def.rs +++ b/modules/src/ics07_tendermint/client_def.rs @@ -110,22 +110,22 @@ impl ClientDef for TendermintClient { // check that the header is not outside the trusting period if header.signed_header.header().time.sub(client_state.trusting_period) >= latest_consensus_state.timestamp { - return Err( - format!("header outside of the trusting period {:?}, {:?}", - latest_consensus_state.timestamp, - header.signed_header.header().time).into(), + return Err(Kind::LowUpdateTimestamp( + header.signed_header.header().time.to_rfc3339(), + latest_consensus_state.timestamp.to_rfc3339()) + .into(), ); }; - - // check monotonicity of height and timestamp - if client_state.latest_height >= header.height() { - return Err( - format!("non monotonic height update {}, {:?}", - client_state.latest_height, - header.height()).into(), - ); - }; + //ALREADY CHECKED + // // check monotonicity of height and timestamp + // if client_state.latest_height >= header.height() { + // return Err( + // format!("non monotonic height update {}, {:?}", + // client_state.latest_height, + // header.height()).into(), + // ); + // }; // check monotonicity of header height vs trusted height. // unclear needed @@ -139,19 +139,17 @@ impl ClientDef for TendermintClient { // check that the versions of the client state and the header match if client_state.latest_height.revision_number != header.height().revision_number { - return Err( - format!("client revision number {} does not match the header's revision number {}", + return Err(Kind::MismatchedRevisions( client_state.latest_height.revision_number, header.height().revision_number).into(), ); }; if latest_consensus_state.timestamp >= header.signed_header.header().time { - //TODO add clock drift ? - return Err( - format!("non monotonic timestamps update {}, {:?}", - client_state.latest_height, - header.height()).into(), + return Err(Kind:: HeaderTimestampOutsideTrustingTime( + header.signed_header.header().time.to_rfc3339(), + latest_consensus_state.timestamp.to_rfc3339()) + .into(), ); }; @@ -166,8 +164,7 @@ impl ClientDef for TendermintClient { ).ok_or_else(|| Kind::ClientArgsTypeMismatch(ClientType::Tendermint))? } None => { - return Err( - format!("Missing consensus state for the client {} at trusted height {:?}", + return Err(Kind::ConsensusStateNotFound( client_id, header.trusted_height).into(), ) @@ -177,7 +174,7 @@ impl ClientDef for TendermintClient { if header.height() == header.trusted_height.increment() { - //adjacent + //adjacent // check that the header's trusted validator set is // the next_validator_set of the trusted consensus state diff --git a/modules/src/mock/header.rs b/modules/src/mock/header.rs index b05c8a7cd8..cd8773cfd4 100644 --- a/modules/src/mock/header.rs +++ b/modules/src/mock/header.rs @@ -51,7 +51,13 @@ impl MockHeader { pub fn new(height: Height) -> Self { Self { height, - timestamp: Default::default(), + timestamp: Timestamp::now(),//Default::default(), + } + } + pub fn new_time(height: Height, timestamp: Timestamp) -> Self { + Self { + height, + timestamp, } } } From 1deda2afad6cd29ebc22b25fc29598387ebe9498 Mon Sep 17 00:00:00 2001 From: cezarad Date: Sun, 20 Jun 2021 11:41:15 +0200 Subject: [PATCH 07/32] failed ping pong - signs --- modules/mc.log | 407 ++++++++++++++++++ .../msgs/transfer.rs | 4 +- modules/src/ics02_client/client_def.rs | 2 +- modules/src/ics02_client/error.rs | 18 +- .../src/ics02_client/handler/update_client.rs | 35 +- .../src/ics04_channel/handler/send_packet.rs | 10 +- modules/src/ics07_tendermint/client_def.rs | 235 ++++------ modules/src/ics07_tendermint/client_state.rs | 1 - modules/src/ics07_tendermint/error.rs | 8 +- modules/src/ics07_tendermint/header.rs | 9 +- modules/src/ics07_tendermint/mod.rs | 2 +- modules/src/ics07_tendermint/predicates.rs | 121 ++++-- modules/src/ics18_relayer/utils.rs | 20 +- modules/src/ics26_routing/handler.rs | 1 - modules/src/mock/context.rs | 4 + modules/src/mock/header.rs | 7 +- modules/src/mock/host.rs | 7 +- 17 files changed, 641 insertions(+), 250 deletions(-) create mode 100644 modules/mc.log diff --git a/modules/mc.log b/modules/mc.log new file mode 100644 index 0000000000..a4e5349fb8 --- /dev/null +++ b/modules/mc.log @@ -0,0 +1,407 @@ +@!@!@STARTMSG 2262:0 @!@!@ +TLC2 Version 2.15 of Day Month 20?? (rev: 920e6fa) +@!@!@ENDMSG 2262 @!@!@ +@!@!@STARTMSG 2401:3 @!@!@ +Please run the Java VM, which executes TLC with a throughput optimized garbage collector, by passing the "-XX:+UseParallelGC" property. +@!@!@ENDMSG 2401 @!@!@ +@!@!@STARTMSG 2187:0 @!@!@ +Running breadth-first search Model-Checking with fp 94 and seed 965814849019522492 with 8 workers on 8 cores with 4096MB heap and 64MB offheap memory [pid: 44931] (Mac OS X 10.16 x86_64, Oracle Corporation 10 x86_64, MSBDiskFPSet, DiskStateQueue). +@!@!@ENDMSG 2187 @!@!@ +@!@!@STARTMSG 2220:0 @!@!@ +Starting SANY... +@!@!@ENDMSG 2220 @!@!@ +Parsing file /Users/idragoi/Documents/GitHub/ibc-rs/modules/tests/support/model_based/IBCTests_ICS03ConnectionOpenConfirmOKTest.tla +Parsing file /Users/idragoi/Documents/GitHub/ibc-rs/modules/tests/support/model_based/IBCTests.tla +Parsing file /Users/idragoi/Documents/GitHub/ibc-rs/modules/tests/support/model_based/IBC.tla +Parsing file /Users/idragoi/Documents/GitHub/ibc-rs/modules/tests/support/model_based/ICS02.tla +Parsing file /Users/idragoi/Documents/GitHub/ibc-rs/modules/tests/support/model_based/ICS03.tla +Parsing file /Users/idragoi/Documents/GitHub/ibc-rs/modules/tests/support/model_based/IBCDefinitions.tla +Parsing file /private/var/folders/j1/w2g38g0s1d10s9kpwcn6fywm00lx47/T/Integers.tla (jar:file:/Users/idragoi/Documents/GitHub/ibc-rs/modules/.modelator/tla2tools-v1.8.0.jar!/tla2sany/StandardModules/Integers.tla) +Parsing file /private/var/folders/j1/w2g38g0s1d10s9kpwcn6fywm00lx47/T/FiniteSets.tla (jar:file:/Users/idragoi/Documents/GitHub/ibc-rs/modules/.modelator/tla2tools-v1.8.0.jar!/tla2sany/StandardModules/FiniteSets.tla) +Parsing file /private/var/folders/j1/w2g38g0s1d10s9kpwcn6fywm00lx47/T/TLC.tla (jar:file:/Users/idragoi/Documents/GitHub/ibc-rs/modules/.modelator/tla2tools-v1.8.0.jar!/tla2sany/StandardModules/TLC.tla) +Parsing file /private/var/folders/j1/w2g38g0s1d10s9kpwcn6fywm00lx47/T/Naturals.tla (jar:file:/Users/idragoi/Documents/GitHub/ibc-rs/modules/.modelator/tla2tools-v1.8.0.jar!/tla2sany/StandardModules/Naturals.tla) +Parsing file /private/var/folders/j1/w2g38g0s1d10s9kpwcn6fywm00lx47/T/Sequences.tla (jar:file:/Users/idragoi/Documents/GitHub/ibc-rs/modules/.modelator/tla2tools-v1.8.0.jar!/tla2sany/StandardModules/Sequences.tla) +Semantic processing of module Naturals +Semantic processing of module Integers +Semantic processing of module Sequences +Semantic processing of module FiniteSets +Semantic processing of module TLC +Semantic processing of module IBCDefinitions +Semantic processing of module ICS02 +Semantic processing of module ICS03 +Semantic processing of module IBC +Semantic processing of module IBCTests +Semantic processing of module IBCTests_ICS03ConnectionOpenConfirmOKTest +@!@!@STARTMSG 2219:0 @!@!@ +SANY finished. +@!@!@ENDMSG 2219 @!@!@ +@!@!@STARTMSG 2185:0 @!@!@ +Starting... (2021-06-20 10:17:41) +@!@!@ENDMSG 2185 @!@!@ +@!@!@STARTMSG 2189:0 @!@!@ +Computing initial states... +@!@!@ENDMSG 2189 @!@!@ +@!@!@STARTMSG 2190:0 @!@!@ +Finished computing initial states: 1 distinct state generated at 2021-06-20 10:17:42. +@!@!@ENDMSG 2190 @!@!@ +@!@!@STARTMSG 2200:0 @!@!@ +Progress(6) at 2021-06-20 10:17:45: 376,807 states generated (376,807 s/min), 11,083 distinct states found (11,083 ds/min), 6,513 states left on queue. +@!@!@ENDMSG 2200 @!@!@ +@!@!@STARTMSG 2110:1 @!@!@ +Invariant ICS03ConnectionOpenConfirmOKTestNeg is violated. +@!@!@ENDMSG 2110 @!@!@ +@!@!@STARTMSG 2121:1 @!@!@ +The behavior up to this point is: +@!@!@ENDMSG 2121 @!@!@ +@!@!@STARTMSG 2217:4 @!@!@ +1: +/\ actionOutcome = "None" +/\ chains = [ chainA |-> + [ height |-> 1, + clients |-> (0 :> [heights |-> {}]), + clientIdCounter |-> 0, + connections |-> + ( 0 :> + [ chainId |-> "-1", + clientId |-> -1, + counterpartyChainId |-> "-1", + counterpartyClientId |-> -1, + counterpartyConnectionId |-> -1, + connectionId |-> -1, + state |-> "Uninitialized" ] ), + connectionIdCounter |-> 0, + connectionProofs |-> {} ], + chainB |-> + [ height |-> 1, + clients |-> (0 :> [heights |-> {}]), + clientIdCounter |-> 0, + connections |-> + ( 0 :> + [ chainId |-> "-1", + clientId |-> -1, + counterpartyChainId |-> "-1", + counterpartyClientId |-> -1, + counterpartyConnectionId |-> -1, + connectionId |-> -1, + state |-> "Uninitialized" ] ), + connectionIdCounter |-> 0, + connectionProofs |-> {} ] ] +/\ action = [type |-> "None"] + +@!@!@ENDMSG 2217 @!@!@ +@!@!@STARTMSG 2217:4 @!@!@ +2: +/\ actionOutcome = "Ics02CreateOk" +/\ chains = [ chainA |-> + [ height |-> 2, + clients |-> (0 :> [heights |-> {2}]), + clientIdCounter |-> 1, + connections |-> + ( 0 :> + [ chainId |-> "-1", + clientId |-> -1, + counterpartyChainId |-> "-1", + counterpartyClientId |-> -1, + counterpartyConnectionId |-> -1, + connectionId |-> -1, + state |-> "Uninitialized" ] ), + connectionIdCounter |-> 0, + connectionProofs |-> {} ], + chainB |-> + [ height |-> 1, + clients |-> (0 :> [heights |-> {}]), + clientIdCounter |-> 0, + connections |-> + ( 0 :> + [ chainId |-> "-1", + clientId |-> -1, + counterpartyChainId |-> "-1", + counterpartyClientId |-> -1, + counterpartyConnectionId |-> -1, + connectionId |-> -1, + state |-> "Uninitialized" ] ), + connectionIdCounter |-> 0, + connectionProofs |-> {} ] ] +/\ action = [ type |-> "Ics02CreateClient", + chainId |-> "chainA", + clientState |-> 2, + consensusState |-> 2 ] + +@!@!@ENDMSG 2217 @!@!@ +@!@!@STARTMSG 2217:4 @!@!@ +3: +/\ actionOutcome = "Ics03ConnectionOpenInitOk" +/\ chains = [ chainA |-> + [ height |-> 3, + clients |-> (0 :> [heights |-> {2}]), + clientIdCounter |-> 1, + connections |-> + ( 0 :> + [ chainId |-> "chainA", + clientId |-> 0, + counterpartyChainId |-> "chainB", + counterpartyClientId |-> 0, + counterpartyConnectionId |-> -1, + connectionId |-> 0, + state |-> "Init" ] ), + connectionIdCounter |-> 1, + connectionProofs |-> {} ], + chainB |-> + [ height |-> 1, + clients |-> (0 :> [heights |-> {}]), + clientIdCounter |-> 0, + connections |-> + ( 0 :> + [ chainId |-> "-1", + clientId |-> -1, + counterpartyChainId |-> "-1", + counterpartyClientId |-> -1, + counterpartyConnectionId |-> -1, + connectionId |-> -1, + state |-> "Uninitialized" ] ), + connectionIdCounter |-> 0, + connectionProofs |-> + { [ type |-> "Ics03ConnectionOpenInit", + chainId |-> "chainA", + clientId |-> 0, + counterpartyChainId |-> "chainB", + counterpartyClientId |-> 0 ] } ] ] +/\ action = [ type |-> "Ics03ConnectionOpenInit", + chainId |-> "chainA", + clientId |-> 0, + counterpartyChainId |-> "chainB", + counterpartyClientId |-> 0 ] + +@!@!@ENDMSG 2217 @!@!@ +@!@!@STARTMSG 2217:4 @!@!@ +4: +/\ actionOutcome = "Ics02CreateOk" +/\ chains = [ chainA |-> + [ height |-> 3, + clients |-> (0 :> [heights |-> {2}]), + clientIdCounter |-> 1, + connections |-> + ( 0 :> + [ chainId |-> "chainA", + clientId |-> 0, + counterpartyChainId |-> "chainB", + counterpartyClientId |-> 0, + counterpartyConnectionId |-> -1, + connectionId |-> 0, + state |-> "Init" ] ), + connectionIdCounter |-> 1, + connectionProofs |-> {} ], + chainB |-> + [ height |-> 2, + clients |-> (0 :> [heights |-> {1}]), + clientIdCounter |-> 1, + connections |-> + ( 0 :> + [ chainId |-> "-1", + clientId |-> -1, + counterpartyChainId |-> "-1", + counterpartyClientId |-> -1, + counterpartyConnectionId |-> -1, + connectionId |-> -1, + state |-> "Uninitialized" ] ), + connectionIdCounter |-> 0, + connectionProofs |-> + { [ type |-> "Ics03ConnectionOpenInit", + chainId |-> "chainA", + clientId |-> 0, + counterpartyChainId |-> "chainB", + counterpartyClientId |-> 0 ] } ] ] +/\ action = [ type |-> "Ics02CreateClient", + chainId |-> "chainB", + clientState |-> 1, + consensusState |-> 1 ] + +@!@!@ENDMSG 2217 @!@!@ +@!@!@STARTMSG 2217:4 @!@!@ +5: +/\ actionOutcome = "Ics03ConnectionOpenTryOk" +/\ chains = [ chainA |-> + [ height |-> 3, + clients |-> (0 :> [heights |-> {2}]), + clientIdCounter |-> 1, + connections |-> + ( 0 :> + [ chainId |-> "chainA", + clientId |-> 0, + counterpartyChainId |-> "chainB", + counterpartyClientId |-> 0, + counterpartyConnectionId |-> -1, + connectionId |-> 0, + state |-> "Init" ] ), + connectionIdCounter |-> 1, + connectionProofs |-> + { [ type |-> "Ics03ConnectionOpenTry", + chainId |-> "chainB", + clientState |-> 1, + clientId |-> 0, + counterpartyChainId |-> "chainA", + counterpartyClientId |-> 0, + previousConnectionId |-> -1, + counterpartyConnectionId |-> 0 ] } ], + chainB |-> + [ height |-> 3, + clients |-> (0 :> [heights |-> {1}]), + clientIdCounter |-> 1, + connections |-> + ( 0 :> + [ chainId |-> "chainB", + clientId |-> 0, + counterpartyChainId |-> "chainA", + counterpartyClientId |-> 0, + counterpartyConnectionId |-> 0, + connectionId |-> 0, + state |-> "TryOpen" ] ), + connectionIdCounter |-> 1, + connectionProofs |-> + { [ type |-> "Ics03ConnectionOpenInit", + chainId |-> "chainA", + clientId |-> 0, + counterpartyChainId |-> "chainB", + counterpartyClientId |-> 0 ] } ] ] +/\ action = [ type |-> "Ics03ConnectionOpenTry", + chainId |-> "chainB", + clientState |-> 1, + clientId |-> 0, + counterpartyChainId |-> "chainA", + counterpartyClientId |-> 0, + previousConnectionId |-> -1, + counterpartyConnectionId |-> 0 ] + +@!@!@ENDMSG 2217 @!@!@ +@!@!@STARTMSG 2217:4 @!@!@ +6: +/\ actionOutcome = "Ics03ConnectionOpenAckOk" +/\ chains = [ chainA |-> + [ height |-> 4, + clients |-> (0 :> [heights |-> {2}]), + clientIdCounter |-> 1, + connections |-> + ( 0 :> + [ chainId |-> "chainA", + clientId |-> 0, + counterpartyChainId |-> "chainB", + counterpartyClientId |-> 0, + counterpartyConnectionId |-> -1, + connectionId |-> 0, + state |-> "Open" ] ), + connectionIdCounter |-> 1, + connectionProofs |-> + { [ type |-> "Ics03ConnectionOpenTry", + chainId |-> "chainB", + clientState |-> 1, + clientId |-> 0, + counterpartyChainId |-> "chainA", + counterpartyClientId |-> 0, + previousConnectionId |-> -1, + counterpartyConnectionId |-> 0 ] } ], + chainB |-> + [ height |-> 3, + clients |-> (0 :> [heights |-> {1}]), + clientIdCounter |-> 1, + connections |-> + ( 0 :> + [ chainId |-> "chainB", + clientId |-> 0, + counterpartyChainId |-> "chainA", + counterpartyClientId |-> 0, + counterpartyConnectionId |-> 0, + connectionId |-> 0, + state |-> "TryOpen" ] ), + connectionIdCounter |-> 1, + connectionProofs |-> + { [ type |-> "Ics03ConnectionOpenInit", + chainId |-> "chainA", + clientId |-> 0, + counterpartyChainId |-> "chainB", + counterpartyClientId |-> 0 ], + [ type |-> "Ics03ConnectionOpenAck", + chainId |-> "chainA", + clientState |-> 2, + counterpartyChainId |-> "chainB", + counterpartyConnectionId |-> 0, + connectionId |-> 0 ] } ] ] +/\ action = [ type |-> "Ics03ConnectionOpenAck", + chainId |-> "chainA", + clientState |-> 2, + counterpartyChainId |-> "chainB", + counterpartyConnectionId |-> 0, + connectionId |-> 0 ] + +@!@!@ENDMSG 2217 @!@!@ +@!@!@STARTMSG 2217:4 @!@!@ +7: +/\ actionOutcome = "Ics03ConnectionOpenConfirmOk" +/\ chains = [ chainA |-> + [ height |-> 4, + clients |-> (0 :> [heights |-> {2}]), + clientIdCounter |-> 1, + connections |-> + ( 0 :> + [ chainId |-> "chainA", + clientId |-> 0, + counterpartyChainId |-> "chainB", + counterpartyClientId |-> 0, + counterpartyConnectionId |-> -1, + connectionId |-> 0, + state |-> "Open" ] ), + connectionIdCounter |-> 1, + connectionProofs |-> + { [ type |-> "Ics03ConnectionOpenTry", + chainId |-> "chainB", + clientState |-> 1, + clientId |-> 0, + counterpartyChainId |-> "chainA", + counterpartyClientId |-> 0, + previousConnectionId |-> -1, + counterpartyConnectionId |-> 0 ] } ], + chainB |-> + [ height |-> 4, + clients |-> (0 :> [heights |-> {1}]), + clientIdCounter |-> 1, + connections |-> + ( 0 :> + [ chainId |-> "chainB", + clientId |-> 0, + counterpartyChainId |-> "chainA", + counterpartyClientId |-> 0, + counterpartyConnectionId |-> 0, + connectionId |-> 0, + state |-> "Open" ] ), + connectionIdCounter |-> 1, + connectionProofs |-> + { [ type |-> "Ics03ConnectionOpenInit", + chainId |-> "chainA", + clientId |-> 0, + counterpartyChainId |-> "chainB", + counterpartyClientId |-> 0 ], + [ type |-> "Ics03ConnectionOpenAck", + chainId |-> "chainA", + clientState |-> 2, + counterpartyChainId |-> "chainB", + counterpartyConnectionId |-> 0, + connectionId |-> 0 ] } ] ] +/\ action = [ type |-> "Ics03ConnectionOpenConfirm", + chainId |-> "chainB", + clientState |-> 1, + counterpartyChainId |-> "chainA", + counterpartyConnectionId |-> 0, + connectionId |-> 0 ] + +@!@!@ENDMSG 2217 @!@!@ +@!@!@STARTMSG 2200:0 @!@!@ +Progress(7) at 2021-06-20 10:17:46: 626,675 states generated (8,044,608 s/min), 14,852 distinct states found (190,654 ds/min), 6,934 states left on queue. +@!@!@ENDMSG 2200 @!@!@ +@!@!@STARTMSG 2199:0 @!@!@ +626675 states generated, 14852 distinct states found, 6934 states left on queue. +@!@!@ENDMSG 2199 @!@!@ +@!@!@STARTMSG 2194:0 @!@!@ +The depth of the complete state graph search is 7. +@!@!@ENDMSG 2194 @!@!@ +@!@!@STARTMSG 2186:0 @!@!@ +Finished in 4677ms at (2021-06-20 10:17:46) +@!@!@ENDMSG 2186 @!@!@ diff --git a/modules/src/application/ics20_fungible_token_transfer/msgs/transfer.rs b/modules/src/application/ics20_fungible_token_transfer/msgs/transfer.rs index 1994b2192b..529602152c 100644 --- a/modules/src/application/ics20_fungible_token_transfer/msgs/transfer.rs +++ b/modules/src/application/ics20_fungible_token_transfer/msgs/transfer.rs @@ -109,6 +109,8 @@ pub mod test_util { use super::MsgTransfer; use crate::timestamp::Timestamp; + use std::ops::Add; + use std::time::Duration; // Returns a dummy `RawMsgTransfer`, for testing only! pub fn get_dummy_msg_transfer(height: u64) -> MsgTransfer { @@ -120,7 +122,7 @@ pub mod test_util { token: None, sender: id.clone(), receiver: id, - timeout_timestamp: Timestamp::from_nanoseconds(1).unwrap(), + timeout_timestamp: Timestamp::now().add(Duration::from_secs(10)).unwrap(), timeout_height: Height { revision_number: 0, revision_height: height, diff --git a/modules/src/ics02_client/client_def.rs b/modules/src/ics02_client/client_def.rs index f96a42419c..fda8e859c2 100644 --- a/modules/src/ics02_client/client_def.rs +++ b/modules/src/ics02_client/client_def.rs @@ -176,7 +176,7 @@ impl ClientDef for AnyClient { fn check_header_and_update_state( &self, ctx: &dyn ClientReader, - client_id:ClientId, + client_id: ClientId, client_state: AnyClientState, header: AnyHeader, ) -> Result<(AnyClientState, AnyConsensusState), Box> { diff --git a/modules/src/ics02_client/error.rs b/modules/src/ics02_client/error.rs index e146770b5b..d00ad7caed 100644 --- a/modules/src/ics02_client/error.rs +++ b/modules/src/ics02_client/error.rs @@ -7,8 +7,8 @@ use crate::ics02_client::client_type::ClientType; use crate::ics23_commitment::error::Error as Ics23Error; use crate::ics24_host::error::ValidationKind; use crate::ics24_host::identifier::ClientId; -use crate::Height; use crate::timestamp::Timestamp; +use crate::Height; use tendermint::hash::Hash; pub type Error = anomaly::Error; @@ -119,7 +119,7 @@ pub enum Kind { InsufficientVotingPower(String), #[error("Timestamp none or {0} and now {1}")] - InvalidConsensusStateTimestamp(Timestamp,Timestamp), + InvalidConsensusStateTimestamp(Timestamp, Timestamp), /// Not enough trust because insufficient validators overlap #[error("not enough trust because insufficient validators overlap: {0}")] @@ -130,24 +130,24 @@ pub enum Kind { InvalidValidatorSet(Hash, Hash), #[error("not withing trusting period: expires_at={0} now={1}")] - ClientStateNotWithinTrustPeriod (Timestamp,Timestamp), + ClientStateNotWithinTrustPeriod(Timestamp, Timestamp), #[error("header not withing trusting period: expires_at={0} now={1}")] - HeaderNotWithinTrustPeriod (Timestamp,Timestamp), + HeaderNotWithinTrustPeriod(Timestamp, Timestamp), - #[error("Header timestamp {0} is outside the trusting period w.r.t. consenus state timestamp{1}")] - HeaderTimestampOutsideTrustingTime(String,String), + #[error( + "Header timestamp {0} is outside the trusting period w.r.t. consenus state timestamp{1}" + )] + HeaderTimestampOutsideTrustingTime(String, String), #[error("Header revision {0} and client state revision {1} should coincide")] - MismatchedRevisions(u64,u64), + MismatchedRevisions(u64, u64), #[error(" hearder height {0} must be at greater than current client height {1}")] LowUpdateHeight(Height, Height), // #[error(" hearder timestamp {0} must be at greater than current client consensus state timestamp {1}")] // LowUpdateTimestamp(Timestamp, Timestamp), - - #[error(" hearder timestamp {0} must be at greater than current client consensus state timestamp {1}")] LowUpdateTimestamp(String, String), diff --git a/modules/src/ics02_client/handler/update_client.rs b/modules/src/ics02_client/handler/update_client.rs index 8fc22535cb..5b2a3b273e 100644 --- a/modules/src/ics02_client/handler/update_client.rs +++ b/modules/src/ics02_client/handler/update_client.rs @@ -54,21 +54,31 @@ pub fn process( } // Read consensus state from the host chain store. - let latest_consensus_state = ctx.consensus_state(&client_id, client_state.latest_height()) - .ok_or_else(|| Kind::ConsensusStateNotFound(client_id.clone(), client_state.latest_height()))?; + let latest_consensus_state = ctx + .consensus_state(&client_id, client_state.latest_height()) + .ok_or_else(|| { + Kind::ConsensusStateNotFound(client_id.clone(), client_state.latest_height()) + })?; info!("latest conseus state {:?}", latest_consensus_state); - let duration = - Timestamp::now().duration_since(&latest_consensus_state.timestamp()) - .ok_or_else(|| Kind::InvalidConsensusStateTimestamp(latest_consensus_state.timestamp(),Timestamp::now()))?; - - if client_state.expired(duration){ - return Err(Kind::ClientStateNotWithinTrustPeriod(latest_consensus_state.timestamp(),Timestamp::now()).into()); + let duration = Timestamp::now() + .duration_since(&latest_consensus_state.timestamp()) + .ok_or_else(|| { + Kind::InvalidConsensusStateTimestamp( + latest_consensus_state.timestamp(), + Timestamp::now(), + ) + })?; + + if client_state.expired(duration) { + return Err(Kind::ClientStateNotWithinTrustPeriod( + latest_consensus_state.timestamp(), + Timestamp::now(), + ) + .into()); } - - // Use client_state to validate the new header against the latest consensus_state. // This function will return the new client_state (its latest_height changed) and a // consensus_state obtained from header. These will be later persisted by the keeper. @@ -110,8 +120,8 @@ mod tests { use crate::mock::context::MockContext; use crate::mock::header::MockHeader; use crate::test_utils::get_dummy_account_id; - use crate::Height; use crate::timestamp::Timestamp; + use crate::Height; #[test] fn test_update_client_ok() { @@ -148,7 +158,8 @@ mod tests { assert_eq!( upd_res.client_state, AnyClientState::Mock(MockClientState(MockHeader::new_time( - msg.header.height(),timestamp + msg.header.height(), + timestamp ))) ) } diff --git a/modules/src/ics04_channel/handler/send_packet.rs b/modules/src/ics04_channel/handler/send_packet.rs index 34ac984344..d71277ff32 100644 --- a/modules/src/ics04_channel/handler/send_packet.rs +++ b/modules/src/ics04_channel/handler/send_packet.rs @@ -131,10 +131,10 @@ mod tests { use crate::ics04_channel::packet::Packet; use crate::ics24_host::identifier::{ChannelId, ClientId, ConnectionId, PortId}; use crate::mock::context::MockContext; - use crate::timestamp::ZERO_DURATION; use crate::timestamp::Timestamp; - use std::time::Duration; + use crate::timestamp::ZERO_DURATION; use std::ops::Add; + use std::time::Duration; #[test] fn send_packet_processing() { @@ -148,8 +148,10 @@ mod tests { let context = MockContext::default(); let timestamp = Timestamp::now().add(Duration::from_secs(10)); - - let mut packet: Packet = get_dummy_raw_packet(1, timestamp.unwrap().as_nanoseconds()).try_into().unwrap(); + //CD:TODO remove unwrap + let mut packet: Packet = get_dummy_raw_packet(1, timestamp.unwrap().as_nanoseconds()) + .try_into() + .unwrap(); packet.sequence = 1.into(); packet.data = vec![0]; diff --git a/modules/src/ics07_tendermint/client_def.rs b/modules/src/ics07_tendermint/client_def.rs index 492bfbbabc..220c983762 100644 --- a/modules/src/ics07_tendermint/client_def.rs +++ b/modules/src/ics07_tendermint/client_def.rs @@ -2,10 +2,10 @@ use ibc_proto::ibc::core::commitment::v1::MerkleProof; use crate::ics02_client::client_consensus::AnyConsensusState; use crate::ics02_client::client_def::ClientDef; -use crate::ics02_client::error::Kind; use crate::ics02_client::client_state::AnyClientState; -use crate::ics02_client::context::ClientReader; use crate::ics02_client::client_type::ClientType; +use crate::ics02_client::context::ClientReader; +use crate::ics02_client::error::Kind; use crate::ics03_connection::connection::ConnectionEnd; use crate::ics04_channel::channel::ChannelEnd; use crate::ics04_channel::packet::Sequence; @@ -18,14 +18,11 @@ use crate::ics23_commitment::commitment::{CommitmentPrefix, CommitmentProofBytes use crate::ics24_host::identifier::ConnectionId; use crate::ics24_host::identifier::{ChannelId, ClientId, PortId}; use crate::Height; -use std::ops::Sub; -use tendermint::validator::Set; use tendermint::trust_threshold::TrustThresholdFraction; -//use tendermint::Time; +use tendermint::validator::Set; use crate::downcast; - #[derive(Clone, Debug, PartialEq, Eq)] pub struct TendermintClient; @@ -41,189 +38,115 @@ impl ClientDef for TendermintClient { client_state: Self::ClientState, header: Self::Header, ) -> Result<(Self::ClientState, Self::ConsensusState), Box> { - - - - - // DONE in HANDLER - // if !client_state.frozen_height.is_zero(){ - // return Err( - // format!("client is frozen at height ({:?})", - // client_state.frozen_height).into(), - // ); - // } - - // // check that the client did not expired - // if Time::now().sub(client_state.trusting_period) >= latest_consensus_state.timestamp { - // return Err( - // format!("consensus state expired; it's outside of the trusting period {:?}, {:?}", - // latest_consensus_state.timestamp, - // Time::now()).into(), - // ); - // }; - - - if client_state.latest_height() >= header.height() { - return Err(Kind::LowUpdateHeight( - header.height(), client_state.latest_height).into(), - ); - } - - if header.height().is_zero() { - return Err(Kind::InvalidHeaderHeight(header.height()).into()); - } - - - // check if a consensus state is already installed; if so it should - // match the untrusted header. - match ctx.consensus_state(&client_id, header.height()){ - //could the header height be zero ? - Some(cs) => { - let consensus_state = downcast!( - cs => AnyConsensusState::Tendermint - ).ok_or_else(|| Kind::ClientArgsTypeMismatch(ClientType::Tendermint))?; - - if consensus_state != ConsensusState::from(header.clone()){ - //freeze the client and return the installed consensus state - return Ok((client_state.with_set_frozen(header.height()), - consensus_state)) - } + // check if a consensus state is already installed; if so it should + // match the untrusted header. + if let Some(cs) = ctx.consensus_state(&client_id, header.height()) { + //could the header height be zero ? + let consensus_state = downcast!( + cs => AnyConsensusState::Tendermint + ) + .ok_or_else(|| Kind::ClientArgsTypeMismatch(ClientType::Tendermint))?; + + if consensus_state != ConsensusState::from(header.clone()) { + //freeze the client and return the installed consensus state + return Ok(( + client_state.with_set_frozen(header.height()), + consensus_state, + )); } - None =>{} - } + }; - let latest_consensus_state = match ctx.consensus_state(&client_id, client_state.latest_height){ - //could the header height be zero ? - Some(cs) => { - downcast!( + let latest_consensus_state = + match ctx.consensus_state(&client_id, client_state.latest_height) { + //could the header height be zero ? + Some(cs) => downcast!( cs => AnyConsensusState::Tendermint - ).ok_or_else(|| Kind::ClientArgsTypeMismatch(ClientType::Tendermint))? + ) + .ok_or_else(|| Kind::ClientArgsTypeMismatch(ClientType::Tendermint))?, + None => { + return Err(Kind::ConsensusStateNotFound( + client_id.clone(), + client_state.latest_height, + ) + .into()); } - None =>{ - return Err( - Kind::ConsensusStateNotFound(client_id.clone(), - client_state.latest_height).into(), - ); - } - }; - - - // check that the header is not outside the trusting period - if header.signed_header.header().time.sub(client_state.trusting_period) >= latest_consensus_state.timestamp { - return Err(Kind::LowUpdateTimestamp( - header.signed_header.header().time.to_rfc3339(), - latest_consensus_state.timestamp.to_rfc3339()) - .into(), - ); - }; + }; - //ALREADY CHECKED - // // check monotonicity of height and timestamp - // if client_state.latest_height >= header.height() { - // return Err( - // format!("non monotonic height update {}, {:?}", - // client_state.latest_height, - // header.height()).into(), - // ); - // }; + let pred = Predicates::default(); - // check monotonicity of header height vs trusted height. - // unclear needed - if header.trusted_height >= header.height() { - return Err( - format!("non monotonic height update w.r.t trusted header {}, {:?}", - header.trusted_height, - header.height()).into(), - ); - }; + pred.monotonicity_checks(latest_consensus_state, header.clone(), client_state.clone())?; // check that the versions of the client state and the header match if client_state.latest_height.revision_number != header.height().revision_number { return Err(Kind::MismatchedRevisions( - client_state.latest_height.revision_number, - header.height().revision_number).into(), - ); + client_state.latest_height.revision_number, + header.height().revision_number, + ) + .into()); }; - if latest_consensus_state.timestamp >= header.signed_header.header().time { - return Err(Kind:: HeaderTimestampOutsideTrustingTime( - header.signed_header.header().time.to_rfc3339(), - latest_consensus_state.timestamp.to_rfc3339()) - .into(), - ); + let trusted_consensus_state = match ctx.consensus_state(&client_id, header.trusted_height) { + Some(ts) => downcast!( + ts => AnyConsensusState::Tendermint + ) + .ok_or_else(|| Kind::ClientArgsTypeMismatch(ClientType::Tendermint))?, + None => { + return Err(Kind::ConsensusStateNotFound(client_id, header.trusted_height).into()) + } }; - - - - let trusted_consensus_state = - match ctx.consensus_state(&client_id, header.trusted_height) { - Some(ts) => { - downcast!( - ts => AnyConsensusState::Tendermint - ).ok_or_else(|| Kind::ClientArgsTypeMismatch(ClientType::Tendermint))? - } - None => { - return Err(Kind::ConsensusStateNotFound( - client_id, - header.trusted_height).into(), - ) - } - }; - - - if header.height() == header.trusted_height.increment() { - //adjacent + //adjacent - // check that the header's trusted validator set is - // the next_validator_set of the trusted consensus state + // check that the header's trusted validator set is + // the next_validator_set of the trusted consensus state if Set::hash(&header.validator_set) != trusted_consensus_state.next_validators_hash { return Err(Kind::InvalidValidatorSet( - trusted_consensus_state.next_validators_hash, - Set::hash(&header.validator_set) - ).into(), + trusted_consensus_state.next_validators_hash, + Set::hash(&header.validator_set), ) + .into()); } - let pred = Predicates::default(); - // check that the validators that sign the commit of the untrusted header - // have 2/3 of the voting power of the current validator set. - match pred.voting_power_in(&header.signed_header,&header.validator_set,TrustThresholdFraction::TWO_THIRDS){ - Err(e) => { return Err(Kind::InsufficientVotingPower(e.to_string()).into()); } - _ =>{} - }; - - - - }else{ - //Non-adjacent - let pred = Predicates::default(); + // check that the validators that sign the commit of the untrusted header + // have 2/3 of the voting power of the current validator set. + if let Err(e) = pred.voting_power_in( + &header.signed_header, + &header.validator_set, + TrustThresholdFraction::TWO_THIRDS, + ) { + return Err(Kind::InsufficientVotingPower(e.to_string()).into()); + } + } else { + //Non-adjacent //check that a subset of the trusted validator set, having 1/3 of the voting power - //signes the commit of the untrusted header - match pred.voting_power_in(&header.signed_header,&header.trusted_validator_set,TrustThresholdFraction::default()){ - Err(e) => { return Err(Kind::NotEnoughTrustedValsSigned(e.to_string()).into());} - _ => {} - }; + //signes the commit of the untrusted header + if let Err(e) = pred.voting_power_in( + &header.signed_header, + &header.trusted_validator_set, + TrustThresholdFraction::default(), + ) { + return Err(Kind::NotEnoughTrustedValsSigned(e.to_string()).into()); + }; - // check that the validators that sign the commit of the untrusted header - // have 2/3 of the voting power of the current validator set. - match pred.voting_power_in(&header.signed_header,&header.validator_set,TrustThresholdFraction::TWO_THIRDS){ - Err(e) => { return Err(Kind::InsufficientVotingPower(e.to_string()).into()); } - _ =>{} + // check that the validators that sign the commit of the untrusted header + // have 2/3 of the voting power of the current validator set. + if let Err(e) = pred.voting_power_in( + &header.signed_header, + &header.validator_set, + TrustThresholdFraction::TWO_THIRDS, + ) { + return Err(Kind::InsufficientVotingPower(e.to_string()).into()); }; } - // TODO: Additional verifications should be implemented here. - Ok(( client_state.with_header(header.clone()), ConsensusState::from(header), )) } - fn verify_client_consensus_state( &self, _client_state: &Self::ClientState, diff --git a/modules/src/ics07_tendermint/client_state.rs b/modules/src/ics07_tendermint/client_state.rs index 6ef376b9f8..92a2326b77 100644 --- a/modules/src/ics07_tendermint/client_state.rs +++ b/modules/src/ics07_tendermint/client_state.rs @@ -111,7 +111,6 @@ impl ClientState { } } - pub fn with_set_frozen(self, h: Height) -> Self { ClientState { frozen_height: h, diff --git a/modules/src/ics07_tendermint/error.rs b/modules/src/ics07_tendermint/error.rs index 0035b12974..c978b93876 100644 --- a/modules/src/ics07_tendermint/error.rs +++ b/modules/src/ics07_tendermint/error.rs @@ -2,8 +2,7 @@ use anomaly::{BoxError, Context}; use thiserror::Error; use crate::ics24_host::error::ValidationKind; -use tendermint::{validator::Info, - account::Id}; +use tendermint::{account::Id, validator::Info}; pub type Error = anomaly::Error; @@ -50,7 +49,7 @@ impl Kind { } #[derive(Clone, Debug, Error)] -pub enum VerificationError{ +pub enum VerificationError { #[error("Couldn't verify signature `{signature:?}` with validator `{validator:?}` on sign_bytes `{sign_bytes:?}`")] InvalidSignature { /// Signature as a byte array @@ -68,7 +67,4 @@ pub enum VerificationError{ /// Insufficient signers overlap #[error("insufficient signers overlap {0} {1}")] InsufficientOverlap(u64, u64), - - - } diff --git a/modules/src/ics07_tendermint/header.rs b/modules/src/ics07_tendermint/header.rs index 4230626bf8..85b0b50682 100644 --- a/modules/src/ics07_tendermint/header.rs +++ b/modules/src/ics07_tendermint/header.rs @@ -64,16 +64,15 @@ impl Header { // pub fn header_equality(&self, other_header: &Header) -> bool{ // let other_height = other_header.signed_header.header.height; // let self_height = self.signed_header.header.height; - // //TODO we need signed header eq + // //TODO we need signed header eq // if self.signed_header.header != other_header.signed_header.header - // return false; + // return false; // } // if self.signed_header.commit != other_header.signed_header.commit - // return false; + // return false; // } - // if self.validator_set != other_header.validator_set - + // if self.validator_set != other_header.validator_set // } } diff --git a/modules/src/ics07_tendermint/mod.rs b/modules/src/ics07_tendermint/mod.rs index 5be0aad568..46d08727fb 100644 --- a/modules/src/ics07_tendermint/mod.rs +++ b/modules/src/ics07_tendermint/mod.rs @@ -6,4 +6,4 @@ pub mod consensus_state; pub mod error; pub mod header; pub mod misbehaviour; -pub mod predicates; \ No newline at end of file +pub mod predicates; diff --git a/modules/src/ics07_tendermint/predicates.rs b/modules/src/ics07_tendermint/predicates.rs index 6a1b949cb4..e9f2cad0e6 100644 --- a/modules/src/ics07_tendermint/predicates.rs +++ b/modules/src/ics07_tendermint/predicates.rs @@ -1,28 +1,73 @@ -use tendermint::block::signed_header::SignedHeader; -use tendermint::validator::Set as ValidatorSet; -use tendermint::trust_threshold::TrustThresholdFraction; -use tendermint::trust_threshold::TrustThreshold; -use tendermint::block::{CommitSig,Commit}; -use tendermint::vote::{SignedVote,ValidatorIndex,Vote}; +use crate::ics02_client::error::Kind; +use crate::ics07_tendermint::client_state::ClientState; +use crate::ics07_tendermint::consensus_state::ConsensusState; +use crate::ics07_tendermint::error::VerificationError; +use crate::ics07_tendermint::header::Header; use std::collections::HashSet; use std::convert::TryFrom; -use crate::ics07_tendermint::error::VerificationError; - - -// pub struct VotingPowerTally { -// /// Total voting power -// pub total: u64, -// /// Tallied voting power -// pub tallied: u64, -// /// Trust threshold for voting power -// pub trust_threshold: TrustThresholdFraction, -// } +use std::ops::Sub; +use tendermint::block::signed_header::SignedHeader; +use tendermint::block::{Commit, CommitSig}; +use tendermint::trust_threshold::TrustThreshold; +use tendermint::trust_threshold::TrustThresholdFraction; +use tendermint::validator::Set as ValidatorSet; +use tendermint::vote::{SignedVote, ValidatorIndex, Vote}; #[derive(Copy, Clone, Debug, Default)] pub struct Predicates; -impl Predicates -{ +impl Predicates { + pub fn monotonicity_checks( + &self, + latest_consensus_state: ConsensusState, + header: Header, + client_state: ClientState, + ) -> Result<(), Box> { + if client_state.latest_height() >= header.height() { + return Err(Kind::LowUpdateHeight(header.height(), client_state.latest_height).into()); + } + + if header.height().is_zero() { + return Err(Kind::InvalidHeaderHeight(header.height()).into()); + } + + //check header timestamp is increasing + if latest_consensus_state.timestamp >= header.signed_header.header().time { + return Err(Kind::HeaderTimestampOutsideTrustingTime( + header.signed_header.header().time.to_rfc3339(), + latest_consensus_state.timestamp.to_rfc3339(), + ) + .into()); + }; + + // check that the header is not outside the trusting period + if header + .signed_header + .header() + .time + .sub(client_state.trusting_period) + >= latest_consensus_state.timestamp + { + return Err(Kind::LowUpdateTimestamp( + header.signed_header.header().time.to_rfc3339(), + latest_consensus_state.timestamp.to_rfc3339(), + ) + .into()); + }; + + // check monotonicity of header height vs trusted height. + // unclear needed + if header.trusted_height >= header.height() { + return Err(format!( + "non monotonic height update w.r.t trusted header {}, {:?}", + header.trusted_height, + header.height() + ) + .into()); + }; + + Ok(()) + } /// Compute the voting power in a header and its commit against a validator set. /// @@ -34,7 +79,6 @@ impl Predicates validator_set: &ValidatorSet, trust_threshold: TrustThresholdFraction, ) -> Result<(), Box> { - let signatures = &signed_header.commit.signatures; let mut tallied_voting_power = 0_u64; @@ -50,14 +94,12 @@ impl Predicates .map(|vote| (signature, vote)) }); - let total_voting_power = self.total_power_of(validator_set); + let total_voting_power = self.total_power_of(validator_set); for (signature, vote) in non_absent_votes { // Ensure we only count a validator's power once if seen_validators.contains(&vote.validator_address) { - return Err(VerificationError::DuplicateValidator( - vote.validator_address - ).into()); + return Err(VerificationError::DuplicateValidator(vote.validator_address).into()); } else { seen_validators.insert(vote.validator_address); } @@ -80,17 +122,20 @@ impl Predicates .verify_signature(&sign_bytes, signed_vote.signature()) .is_err() { - return Err((VerificationError::InvalidSignature{ - signature: signed_vote.signature().to_bytes(), - validator: Box::new(validator), - sign_bytes}).into()); + //continue; + return Err((VerificationError::InvalidSignature { + signature: signed_vote.signature().to_bytes(), + validator: Box::new(validator), + sign_bytes, + }) + .into()); } // If the vote is neither absent nor nil, tally its power if signature.is_commit() { tallied_voting_power += validator.power(); - if trust_threshold.is_enough_power(tallied_voting_power,total_voting_power) { - return Ok(()) + if trust_threshold.is_enough_power(tallied_voting_power, total_voting_power) { + return Ok(()); } } else { // It's OK. We include stray signatures (~votes for nil) @@ -98,19 +143,7 @@ impl Predicates } } - return Err(VerificationError::InsufficientOverlap(tallied_voting_power,total_voting_power).into()); - - // let voting_power = VotingPowerTally { - // total: self.total_power_of(validator_set), - // tallied: tallied_voting_power, - // trust_threshold, - // }; - - // if !trust_threshold.is_enough_power(voting_power.tallied,voting_power.total){ - // return Err(format!("bla").into()); - // } - - // Ok(()) + Err(VerificationError::InsufficientOverlap(tallied_voting_power, total_voting_power).into()) } /// Compute the total voting power in a validator set @@ -158,4 +191,4 @@ fn non_absent_vote( validator_index, signature: *signature, }) -} \ No newline at end of file +} diff --git a/modules/src/ics18_relayer/utils.rs b/modules/src/ics18_relayer/utils.rs index a5ca5fbf67..3ea6dc5f2c 100644 --- a/modules/src/ics18_relayer/utils.rs +++ b/modules/src/ics18_relayer/utils.rs @@ -4,6 +4,7 @@ use crate::ics02_client::msgs::ClientMsg; use crate::ics18_relayer::context::Ics18Context; use crate::ics18_relayer::error::{Error, Kind}; use crate::ics24_host::identifier::ClientId; +//use crate::ics07_tendermint::header::Header as TendermintHeader; /// Builds a `ClientMsg::UpdateClient` for a client with id `client_id` running on the `dest` /// context, assuming that the latest header on the source context is `src_header`. @@ -52,7 +53,7 @@ where #[cfg(test)] mod tests { use crate::ics02_client::client_type::ClientType; - use crate::ics02_client::header::Header; + use crate::ics02_client::header::{AnyHeader, Header}; use crate::ics18_relayer::context::Ics18Context; use crate::ics18_relayer::utils::build_client_update_datagram; use crate::ics24_host::identifier::{ChainId, ClientId}; @@ -61,6 +62,7 @@ mod tests { use crate::mock::host::HostType; use crate::Height; use test_env_log::test; + use tracing::debug; #[test] /// Serves to test both ICS 26 `dispatch` & `build_client_update_datagram` functions. @@ -150,7 +152,19 @@ mod tests { // Update client on chain B to latest height of B. // - create the client update message with the latest header from B - let b_latest_header = ctx_b.query_latest_header().unwrap(); + let mut b_latest_header = ctx_b.query_latest_header().unwrap(); + // The test uses LightClientBlock that does not store the trusted height + + b_latest_header = match b_latest_header { + AnyHeader::Tendermint(header) => { + let th = header.height(); + let mut hheader = header.clone(); + hheader.trusted_height = th.decrement().unwrap(); + hheader.wrap_any() + } + AnyHeader::Mock(header) => header.wrap_any(), + }; + assert_eq!( b_latest_header.client_type(), ClientType::Tendermint, @@ -170,6 +184,8 @@ mod tests { ); let client_msg_a = client_msg_a_res.unwrap(); + debug!("client_msg_a = {:?}", client_msg_a); + // - send the message to A let dispatch_res_a = ctx_a.deliver(Ics26Envelope::Ics2Msg(client_msg_a)); let validation_res = ctx_a.validate(); diff --git a/modules/src/ics26_routing/handler.rs b/modules/src/ics26_routing/handler.rs index dd437932a9..5eceeaeda8 100644 --- a/modules/src/ics26_routing/handler.rs +++ b/modules/src/ics26_routing/handler.rs @@ -369,7 +369,6 @@ mod tests { .unwrap(); let msg_transfer = get_dummy_msg_transfer(35); - let msg_transfer_two = get_dummy_msg_transfer(36); let mut msg_to_on_close = diff --git a/modules/src/mock/context.rs b/modules/src/mock/context.rs index 5837fb832a..dfe05a39d7 100644 --- a/modules/src/mock/context.rs +++ b/modules/src/mock/context.rs @@ -1,5 +1,7 @@ //! Implementation of a global context mock. Used in testing handlers of all IBC modules. +use ::tracing::info; + use std::cmp::min; use std::collections::HashMap; use std::error::Error; @@ -227,6 +229,8 @@ impl MockContext { }; let consensus_states = vec![(cs_height, consensus_state)].into_iter().collect(); + info!("Consensus state {:?}", consensus_states); + let client_record = MockClientRecord { client_type, client_state, diff --git a/modules/src/mock/header.rs b/modules/src/mock/header.rs index cd8773cfd4..795f75dabc 100644 --- a/modules/src/mock/header.rs +++ b/modules/src/mock/header.rs @@ -51,14 +51,11 @@ impl MockHeader { pub fn new(height: Height) -> Self { Self { height, - timestamp: Timestamp::now(),//Default::default(), + timestamp: Timestamp::now(), //Default::default(), } } pub fn new_time(height: Height, timestamp: Timestamp) -> Self { - Self { - height, - timestamp, - } + Self { height, timestamp } } } diff --git a/modules/src/mock/host.rs b/modules/src/mock/host.rs index 18f3fb2df0..7f3d0c3c22 100644 --- a/modules/src/mock/host.rs +++ b/modules/src/mock/host.rs @@ -3,6 +3,7 @@ use std::convert::TryFrom; use tendermint::chain::Id as TMChainId; +use tendermint::time::Time; use tendermint_testgen::light_block::TmLightBlock; use tendermint_testgen::{Generator, LightBlock as TestgenLightBlock}; @@ -51,7 +52,8 @@ impl HostBlock { match chain_type { HostType::Mock => HostBlock::Mock(MockHeader { height: Height::new(chain_id.version(), height), - timestamp: Timestamp::from_nanoseconds(1).unwrap(), + timestamp: Timestamp::now(), + //Timestamp::from_nanoseconds(1).unwrap(), }), HostType::SyntheticTendermint => { HostBlock::SyntheticTendermint(Box::new(Self::generate_tm_block(chain_id, height))) @@ -61,8 +63,9 @@ impl HostBlock { pub fn generate_tm_block(chain_id: ChainId, height: u64) -> TmLightBlock { let mut block = TestgenLightBlock::new_default(height).generate().unwrap(); + block.signed_header.header.time = Time::now(); + //block.signed_header.header.height = Height(height); block.signed_header.header.chain_id = TMChainId::try_from(chain_id.to_string()).unwrap(); - block } } From cc5780afcf15841bd7883b0d8d4840d254805e34 Mon Sep 17 00:00:00 2001 From: cezarad Date: Mon, 21 Jun 2021 18:29:05 +0200 Subject: [PATCH 08/32] Update context.rs --- modules/src/mock/context.rs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/modules/src/mock/context.rs b/modules/src/mock/context.rs index dfe05a39d7..01391c464e 100644 --- a/modules/src/mock/context.rs +++ b/modules/src/mock/context.rs @@ -1,6 +1,6 @@ //! Implementation of a global context mock. Used in testing handlers of all IBC modules. -use ::tracing::info; +use ::tracing::{debug,info}; use std::cmp::min; use std::collections::HashMap; @@ -41,6 +41,9 @@ use crate::signer::Signer; use crate::timestamp::Timestamp; use crate::Height; +use crate::ics07_tendermint::predicates::Predicates; +use tendermint::trust_threshold::TrustThresholdFraction; + /// A context implementing the dependencies necessary for testing any IBC module. #[derive(Clone, Debug)] pub struct MockContext { @@ -219,6 +222,15 @@ impl MockContext { self.host_chain_id.clone(), cs_height.revision_height, ); + + let pred = Predicates::default(); + if let Err(_e) = pred.voting_power_in( + &light_block.signed_header, + &light_block.validators, + TrustThresholdFraction::TWO_THIRDS){ + debug!("\n Insufficient Voting Power"); + } + let consensus_state = AnyConsensusState::from(light_block.clone()); let client_state = get_dummy_tendermint_client_state(light_block.signed_header.header); From e63e5b3112a60295769a28477f69e565977e179e Mon Sep 17 00:00:00 2001 From: cezarad Date: Tue, 22 Jun 2021 11:26:52 +0200 Subject: [PATCH 09/32] bla --- modules/src/ics07_tendermint/predicates.rs | 4 +++- modules/src/mock/context.rs | 7 ++++--- modules/src/mock/host.rs | 2 +- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/modules/src/ics07_tendermint/predicates.rs b/modules/src/ics07_tendermint/predicates.rs index e9f2cad0e6..1753b18029 100644 --- a/modules/src/ics07_tendermint/predicates.rs +++ b/modules/src/ics07_tendermint/predicates.rs @@ -12,6 +12,7 @@ use tendermint::trust_threshold::TrustThreshold; use tendermint::trust_threshold::TrustThresholdFraction; use tendermint::validator::Set as ValidatorSet; use tendermint::vote::{SignedVote, ValidatorIndex, Vote}; +//SignedVote, #[derive(Copy, Clone, Debug, Default)] pub struct Predicates; @@ -116,8 +117,9 @@ impl Predicates { vote.signature, ); - // Check vote is valid + let sign_bytes = signed_vote.sign_bytes(); + // Check vote is valid if validator .verify_signature(&sign_bytes, signed_vote.signature()) .is_err() diff --git a/modules/src/mock/context.rs b/modules/src/mock/context.rs index 01391c464e..4d680ec26f 100644 --- a/modules/src/mock/context.rs +++ b/modules/src/mock/context.rs @@ -1,6 +1,6 @@ //! Implementation of a global context mock. Used in testing handlers of all IBC modules. -use ::tracing::{debug,info}; +use ::tracing::info; use std::cmp::min; use std::collections::HashMap; @@ -224,11 +224,12 @@ impl MockContext { ); let pred = Predicates::default(); - if let Err(_e) = pred.voting_power_in( + if let Err(e) = pred.voting_power_in( &light_block.signed_header, &light_block.validators, TrustThresholdFraction::TWO_THIRDS){ - debug!("\n Insufficient Voting Power"); + panic!("{}",e.to_string()); + // info!("\n COntext: Insufficient Voting Power"); } let consensus_state = AnyConsensusState::from(light_block.clone()); diff --git a/modules/src/mock/host.rs b/modules/src/mock/host.rs index 7f3d0c3c22..27680fb8b6 100644 --- a/modules/src/mock/host.rs +++ b/modules/src/mock/host.rs @@ -63,7 +63,7 @@ impl HostBlock { pub fn generate_tm_block(chain_id: ChainId, height: u64) -> TmLightBlock { let mut block = TestgenLightBlock::new_default(height).generate().unwrap(); - block.signed_header.header.time = Time::now(); + //block.signed_header.header.time = Time::now(); //block.signed_header.header.height = Height(height); block.signed_header.header.chain_id = TMChainId::try_from(chain_id.to_string()).unwrap(); block From 2c91fe648ac7985d1341294d2942dd83ed01a95d Mon Sep 17 00:00:00 2001 From: cezarad Date: Tue, 22 Jun 2021 11:33:28 +0200 Subject: [PATCH 10/32] blabla --- Cargo.lock | 11 ----------- Cargo.toml | 12 ++++++------ modules/src/mock/host.rs | 2 +- 3 files changed, 7 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 95268a3392..3c2b080adc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3038,8 +3038,6 @@ dependencies = [ [[package]] name = "tendermint" version = "0.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "831486f28e65c6f6c6f8afb067796f3c470db91a44d177224f8e6287601391b6" dependencies = [ "anomaly", "async-trait", @@ -3047,7 +3045,6 @@ dependencies = [ "chrono", "ed25519", "ed25519-dalek", - "funty", "futures", "num-traits", "once_cell", @@ -3071,8 +3068,6 @@ dependencies = [ [[package]] name = "tendermint-light-client" version = "0.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ed9969bedd65d67f5bdee95fcde4a8e54ba11b3eebb2bfcf24a0d8abb0e10ea" dependencies = [ "anomaly", "contracts", @@ -3093,8 +3088,6 @@ dependencies = [ [[package]] name = "tendermint-proto" version = "0.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32bbc1bc55f09de4d00b5d69aa6b60392ba37c5e4761d869f76065d352bd3360" dependencies = [ "anomaly", "bytes", @@ -3112,8 +3105,6 @@ dependencies = [ [[package]] name = "tendermint-rpc" version = "0.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5379de699d14c3edcddc2d9f30ae42066942b9b88aa81b88f047e4e867680fc5" dependencies = [ "async-trait", "async-tungstenite", @@ -3143,8 +3134,6 @@ dependencies = [ [[package]] name = "tendermint-testgen" version = "0.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bc19930d52024c6c061071a10f92caec0cb6416067e39264c6553eb6c6147f8" dependencies = [ "ed25519-dalek", "gumdrop 0.8.0", diff --git a/Cargo.toml b/Cargo.toml index 82a431efe2..af0583a47a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,9 +12,9 @@ exclude = [ "proto-compiler" ] -# [patch.crates-io] -# tendermint = { git = "https://github.com/informalsystems/tendermint-rs", branch = "master" } -# tendermint-rpc = { git = "https://github.com/informalsystems/tendermint-rs", branch = "master" } -# tendermint-proto = { git = "https://github.com/informalsystems/tendermint-rs", branch = "master" } -# tendermint-light-client = { git = "https://github.com/informalsystems/tendermint-rs", branch = "master" } -# tendermint-testgen = { git = "https://github.com/informalsystems/tendermint-rs", branch = "master" } +[patch.crates-io] +tendermint = { path = "../tendermint-rs/tendermint" } +tendermint-rpc = { path = "../tendermint-rs/rpc" } +tendermint-proto = { path = "../tendermint-rs/proto" } +tendermint-light-client = { path = "../tendermint-rs/light-client" } +tendermint-testgen = { path = "../tendermint-rs/testgen" } diff --git a/modules/src/mock/host.rs b/modules/src/mock/host.rs index 27680fb8b6..ac28882efa 100644 --- a/modules/src/mock/host.rs +++ b/modules/src/mock/host.rs @@ -3,7 +3,7 @@ use std::convert::TryFrom; use tendermint::chain::Id as TMChainId; -use tendermint::time::Time; +//use tendermint::time::Time; use tendermint_testgen::light_block::TmLightBlock; use tendermint_testgen::{Generator, LightBlock as TestgenLightBlock}; From 8d4ca794040e3cb2b1d7393b4c7d07b575f6d970 Mon Sep 17 00:00:00 2001 From: cezarad Date: Tue, 22 Jun 2021 21:00:48 +0200 Subject: [PATCH 11/32] fixed test client_update_ping_pong --- modules/src/lib.rs | 2 +- modules/src/mock/host.rs | 24 ++++++++++++++++-------- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/modules/src/lib.rs b/modules/src/lib.rs index e1cfdc510c..52448f179f 100644 --- a/modules/src/lib.rs +++ b/modules/src/lib.rs @@ -1,6 +1,6 @@ #![allow(clippy::large_enum_variant)] #![deny( - warnings, + //warnings, // missing_docs, trivial_casts, trivial_numeric_casts, diff --git a/modules/src/mock/host.rs b/modules/src/mock/host.rs index ac28882efa..323f41edd9 100644 --- a/modules/src/mock/host.rs +++ b/modules/src/mock/host.rs @@ -1,11 +1,11 @@ //! Host chain types and methods, used by context mock. -use std::convert::TryFrom; +// use std::convert::TryFrom; -use tendermint::chain::Id as TMChainId; -//use tendermint::time::Time; +// use tendermint::chain::Id as TMChainId; +use tendermint::time::Time; use tendermint_testgen::light_block::TmLightBlock; -use tendermint_testgen::{Generator, LightBlock as TestgenLightBlock}; +use tendermint_testgen::{Generator,LightBlock as TestgenLightBlock}; use crate::ics02_client::client_consensus::AnyConsensusState; use crate::ics02_client::header::AnyHeader; @@ -15,6 +15,7 @@ use crate::ics24_host::identifier::ChainId; use crate::mock::header::MockHeader; use crate::timestamp::Timestamp; use crate::Height; +use std::{thread, time}; /// Defines the different types of host chains that a mock context can emulate. /// The variants are as follows: @@ -62,10 +63,17 @@ impl HostBlock { } pub fn generate_tm_block(chain_id: ChainId, height: u64) -> TmLightBlock { - let mut block = TestgenLightBlock::new_default(height).generate().unwrap(); - //block.signed_header.header.time = Time::now(); - //block.signed_header.header.height = Height(height); - block.signed_header.header.chain_id = TMChainId::try_from(chain_id.to_string()).unwrap(); + + //Sleep is required otherwise the generator produces blocks with the same timestamp + //as two block can be generated per second. + let ten_millis = time::Duration::from_millis(1000); + thread::sleep(ten_millis); + let time = Time::now().duration_since(Time::unix_epoch()).unwrap().as_secs(); + + let block = TestgenLightBlock::new_parametrized_default( + chain_id.to_string(), + time, + height).generate().unwrap(); block } } From 87f538a4b16ff994f507eb5c453844f334e2b641 Mon Sep 17 00:00:00 2001 From: cezarad Date: Tue, 22 Jun 2021 22:26:55 +0200 Subject: [PATCH 12/32] fmt + clippy --- modules/src/ics07_tendermint/predicates.rs | 3 +-- modules/src/lib.rs | 2 +- modules/src/mock/context.rs | 11 +++++----- modules/src/mock/host.rs | 24 +++++++++++----------- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/modules/src/ics07_tendermint/predicates.rs b/modules/src/ics07_tendermint/predicates.rs index 1753b18029..11ab6fdf6b 100644 --- a/modules/src/ics07_tendermint/predicates.rs +++ b/modules/src/ics07_tendermint/predicates.rs @@ -117,9 +117,8 @@ impl Predicates { vote.signature, ); - let sign_bytes = signed_vote.sign_bytes(); - // Check vote is valid + // Check vote is valid if validator .verify_signature(&sign_bytes, signed_vote.signature()) .is_err() diff --git a/modules/src/lib.rs b/modules/src/lib.rs index 52448f179f..e1cfdc510c 100644 --- a/modules/src/lib.rs +++ b/modules/src/lib.rs @@ -1,6 +1,6 @@ #![allow(clippy::large_enum_variant)] #![deny( - //warnings, + warnings, // missing_docs, trivial_casts, trivial_numeric_casts, diff --git a/modules/src/mock/context.rs b/modules/src/mock/context.rs index 4d680ec26f..67f62dbdee 100644 --- a/modules/src/mock/context.rs +++ b/modules/src/mock/context.rs @@ -223,14 +223,15 @@ impl MockContext { cs_height.revision_height, ); - let pred = Predicates::default(); + let pred = Predicates::default(); if let Err(e) = pred.voting_power_in( &light_block.signed_header, &light_block.validators, - TrustThresholdFraction::TWO_THIRDS){ - panic!("{}",e.to_string()); - // info!("\n COntext: Insufficient Voting Power"); - } + TrustThresholdFraction::TWO_THIRDS, + ) { + panic!("{}", e.to_string()); + // info!("\n COntext: Insufficient Voting Power"); + } let consensus_state = AnyConsensusState::from(light_block.clone()); let client_state = diff --git a/modules/src/mock/host.rs b/modules/src/mock/host.rs index 323f41edd9..28cbaea798 100644 --- a/modules/src/mock/host.rs +++ b/modules/src/mock/host.rs @@ -5,7 +5,7 @@ // use tendermint::chain::Id as TMChainId; use tendermint::time::Time; use tendermint_testgen::light_block::TmLightBlock; -use tendermint_testgen::{Generator,LightBlock as TestgenLightBlock}; +use tendermint_testgen::{Generator, LightBlock as TestgenLightBlock}; use crate::ics02_client::client_consensus::AnyConsensusState; use crate::ics02_client::header::AnyHeader; @@ -63,18 +63,18 @@ impl HostBlock { } pub fn generate_tm_block(chain_id: ChainId, height: u64) -> TmLightBlock { + //Sleep is required otherwise the generator produces blocks with the same timestamp + //as two block can be generated per second. + let ten_millis = time::Duration::from_millis(1000); + thread::sleep(ten_millis); + let time = Time::now() + .duration_since(Time::unix_epoch()) + .unwrap() + .as_secs(); - //Sleep is required otherwise the generator produces blocks with the same timestamp - //as two block can be generated per second. - let ten_millis = time::Duration::from_millis(1000); - thread::sleep(ten_millis); - let time = Time::now().duration_since(Time::unix_epoch()).unwrap().as_secs(); - - let block = TestgenLightBlock::new_parametrized_default( - chain_id.to_string(), - time, - height).generate().unwrap(); - block + TestgenLightBlock::new_parametrized_default(chain_id.to_string(), time, height) + .generate() + .unwrap() } } From 3b470cc98c5db27e832e19a08ec686c4df9cf9da Mon Sep 17 00:00:00 2001 From: cezarad Date: Tue, 22 Jun 2021 22:44:16 +0200 Subject: [PATCH 13/32] Update context.rs --- modules/src/mock/context.rs | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/modules/src/mock/context.rs b/modules/src/mock/context.rs index 67f62dbdee..1eba0aa0dd 100644 --- a/modules/src/mock/context.rs +++ b/modules/src/mock/context.rs @@ -223,16 +223,6 @@ impl MockContext { cs_height.revision_height, ); - let pred = Predicates::default(); - if let Err(e) = pred.voting_power_in( - &light_block.signed_header, - &light_block.validators, - TrustThresholdFraction::TWO_THIRDS, - ) { - panic!("{}", e.to_string()); - // info!("\n COntext: Insufficient Voting Power"); - } - let consensus_state = AnyConsensusState::from(light_block.clone()); let client_state = get_dummy_tendermint_client_state(light_block.signed_header.header); From 0bed49f694971719c998364bc5bde03de7a6c7c3 Mon Sep 17 00:00:00 2001 From: cezarad Date: Tue, 22 Jun 2021 22:45:03 +0200 Subject: [PATCH 14/32] Update context.rs --- modules/src/mock/context.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/modules/src/mock/context.rs b/modules/src/mock/context.rs index 1eba0aa0dd..e69b80a380 100644 --- a/modules/src/mock/context.rs +++ b/modules/src/mock/context.rs @@ -41,9 +41,6 @@ use crate::signer::Signer; use crate::timestamp::Timestamp; use crate::Height; -use crate::ics07_tendermint::predicates::Predicates; -use tendermint::trust_threshold::TrustThresholdFraction; - /// A context implementing the dependencies necessary for testing any IBC module. #[derive(Clone, Debug)] pub struct MockContext { From 437d3458d08a62d7cf6413a420c796af8727bd13 Mon Sep 17 00:00:00 2001 From: cezarad Date: Tue, 22 Jun 2021 22:47:08 +0200 Subject: [PATCH 15/32] remove comments --- modules/src/ics02_client/handler/update_client.rs | 1 - modules/src/ics07_tendermint/predicates.rs | 2 +- modules/src/ics18_relayer/utils.rs | 1 - modules/src/mock/host.rs | 3 --- 4 files changed, 1 insertion(+), 6 deletions(-) diff --git a/modules/src/ics02_client/handler/update_client.rs b/modules/src/ics02_client/handler/update_client.rs index 5b2a3b273e..d85c163077 100644 --- a/modules/src/ics02_client/handler/update_client.rs +++ b/modules/src/ics02_client/handler/update_client.rs @@ -9,7 +9,6 @@ use crate::ics02_client::context::ClientReader; use crate::ics02_client::error::{Error, Kind}; use crate::ics02_client::events::Attributes; use crate::ics02_client::handler::ClientResult; -//use crate::ics02_client::header::Header; use crate::ics02_client::msgs::update_client::MsgUpdateAnyClient; use crate::ics24_host::identifier::ClientId; use crate::timestamp::Timestamp; diff --git a/modules/src/ics07_tendermint/predicates.rs b/modules/src/ics07_tendermint/predicates.rs index 11ab6fdf6b..0beef46264 100644 --- a/modules/src/ics07_tendermint/predicates.rs +++ b/modules/src/ics07_tendermint/predicates.rs @@ -12,7 +12,7 @@ use tendermint::trust_threshold::TrustThreshold; use tendermint::trust_threshold::TrustThresholdFraction; use tendermint::validator::Set as ValidatorSet; use tendermint::vote::{SignedVote, ValidatorIndex, Vote}; -//SignedVote, + #[derive(Copy, Clone, Debug, Default)] pub struct Predicates; diff --git a/modules/src/ics18_relayer/utils.rs b/modules/src/ics18_relayer/utils.rs index 3ea6dc5f2c..7a9db922ff 100644 --- a/modules/src/ics18_relayer/utils.rs +++ b/modules/src/ics18_relayer/utils.rs @@ -4,7 +4,6 @@ use crate::ics02_client::msgs::ClientMsg; use crate::ics18_relayer::context::Ics18Context; use crate::ics18_relayer::error::{Error, Kind}; use crate::ics24_host::identifier::ClientId; -//use crate::ics07_tendermint::header::Header as TendermintHeader; /// Builds a `ClientMsg::UpdateClient` for a client with id `client_id` running on the `dest` /// context, assuming that the latest header on the source context is `src_header`. diff --git a/modules/src/mock/host.rs b/modules/src/mock/host.rs index 28cbaea798..80a3aa3ade 100644 --- a/modules/src/mock/host.rs +++ b/modules/src/mock/host.rs @@ -1,8 +1,5 @@ //! Host chain types and methods, used by context mock. -// use std::convert::TryFrom; - -// use tendermint::chain::Id as TMChainId; use tendermint::time::Time; use tendermint_testgen::light_block::TmLightBlock; use tendermint_testgen::{Generator, LightBlock as TestgenLightBlock}; From 2d76e2785d4208a97697214678bf75a1f798d85b Mon Sep 17 00:00:00 2001 From: cezarad Date: Thu, 24 Jun 2021 11:08:16 +0200 Subject: [PATCH 16/32] Update host.rs --- modules/src/mock/host.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/src/mock/host.rs b/modules/src/mock/host.rs index 80a3aa3ade..4a3db0b23c 100644 --- a/modules/src/mock/host.rs +++ b/modules/src/mock/host.rs @@ -69,7 +69,7 @@ impl HostBlock { .unwrap() .as_secs(); - TestgenLightBlock::new_parametrized_default(chain_id.to_string(), time, height) + TestgenLightBlock::new_default_with_time_and_chain_id(chain_id.to_string(), time, height) .generate() .unwrap() } From 3417872ac95da0a59309ab3d77905613a6c4f064 Mon Sep 17 00:00:00 2001 From: Romain Ruetschi Date: Thu, 24 Jun 2021 12:27:06 +0200 Subject: [PATCH 17/32] Update to tendermint-rs v0.20.0 --- Cargo.lock | 190 ++++++++++++++++++------------------ modules/Cargo.toml | 10 +- proto/Cargo.toml | 2 +- relayer-cli/Cargo.toml | 8 +- relayer/Cargo.toml | 10 +- relayer/src/chain/cosmos.rs | 2 +- 6 files changed, 111 insertions(+), 111 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index aaf6ad495c..f873e96fb1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -46,9 +46,9 @@ dependencies = [ [[package]] name = "addr2line" -version = "0.15.1" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03345e98af8f3d786b6d9f656ccfa6ac316d954e92bc4841f0bba20789d5fb5a" +checksum = "e7a2e47a1fbe209ee101dd6d61285226744c6c8d3c21c8dc878ba6cb9f467f3a" dependencies = [ "gimli", ] @@ -67,9 +67,9 @@ checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" [[package]] name = "aho-corasick" -version = "0.7.18" +version = "0.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5" dependencies = [ "memchr", ] @@ -104,9 +104,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.40" +version = "1.0.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28b2cd92db5cbd74e8e5028f7e27dd7aa3090e89e4f2a197cc7c8dfb69c7063b" +checksum = "15af2628f6890fe2609a3b91bef4c83450512802e59489f9c1cb1fa5df064a61" [[package]] name = "arrayref" @@ -254,9 +254,9 @@ dependencies = [ [[package]] name = "bitcoin_hashes" -version = "0.9.6" +version = "0.9.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e6d72ba9671cb0929b5620e1bc30cdf5e206ccb3dbaa8964d67f6efc1e16129" +checksum = "7ce18265ec2324ad075345d5814fbeed4f41f0a660055dc78840b74d19b874b1" dependencies = [ "serde", ] @@ -497,9 +497,9 @@ checksum = "ea221b5284a47e40033bf9b66f35f984ec0ea2931eb03505246cd27a963f981b" [[package]] name = "cpufeatures" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed00c67cb5d0a7d64a44f6ad2668db7e7530311dd53ea79bcd4fb022c64911c8" +checksum = "66c99696f6c9dd7f35d486b9d04d7e6e202aa3e8c40d553f2fdf5e7e0c6a71ef" dependencies = [ "libc", ] @@ -569,12 +569,13 @@ dependencies = [ [[package]] name = "crypto-bigint" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "281d926f72b42bf3ba840b88cd53e39f36be9f66e34c8df3fb336372b3753d41" +checksum = "bdc9968be9247fb330af911b91a58a267cbbcfcb8dea88debaf977738950dce5" dependencies = [ "generic-array", "subtle", + "zeroize", ] [[package]] @@ -766,9 +767,9 @@ checksum = "ee2626afccd7561a06cf1367e2950c4718ea04565e20fb5029b6c7d8ad09abcf" [[package]] name = "ecdsa" -version = "0.12.1" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16c4363c082db1a39dc354b9693923252c333bd41c918a64639da87aec1a6288" +checksum = "05cb0ed2d2ce37766ac86c05f66973ace8c51f7f1533bedce8fb79e2b54b3f14" dependencies = [ "der", "elliptic-curve", @@ -809,16 +810,16 @@ checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" [[package]] name = "elliptic-curve" -version = "0.10.2" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59029dd05f60215bbe37eda4b32ba1a142abc8b01a938955b20b92ff0d713e8e" +checksum = "dd035cb119cbc25e91bb6f1abbfe341388ddb47a1fe5e77ca6bcbe231e87580b" dependencies = [ "crypto-bigint", "ff", "generic-array", "group", "pkcs8", - "rand_core 0.6.2", + "rand_core 0.6.3", "subtle", "zeroize", ] @@ -842,7 +843,7 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "63eec06c61e487eecf0f7e6e6372e596a81922c28d33e645d6983ca6493a1af0" dependencies = [ - "rand_core 0.6.2", + "rand_core 0.6.3", "subtle", ] @@ -854,7 +855,7 @@ checksum = "1d34cfa13a63ae058bfa601fe9e313bbdb3746427c1459185464ce0fcf62e1e8" dependencies = [ "cfg-if 1.0.0", "libc", - "redox_syscall 0.2.8", + "redox_syscall 0.2.9", "winapi", ] @@ -1077,7 +1078,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c363a5301b8f153d80747126a04b3c82073b9fe3130571a9d170cacdeaf7912" dependencies = [ "ff", - "rand_core 0.6.2", + "rand_core 0.6.3", "subtle", ] @@ -1198,9 +1199,9 @@ dependencies = [ [[package]] name = "heck" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cbf45460356b7deeb5e3415b5563308c0a9b057c85e12b06ad551f98d0a6ac" +checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" dependencies = [ "unicode-segmentation", ] @@ -1292,9 +1293,9 @@ dependencies = [ [[package]] name = "hyper" -version = "0.14.8" +version = "0.14.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3f71a7eea53a3f8257a7b4795373ff886397178cd634430ea94e12d7fe4fe34" +checksum = "07d6baa1b441335f3ce5098ac421fb6547c46dda735ca1bc6d0153c838f9dd83" dependencies = [ "bytes", "futures-channel", @@ -1306,7 +1307,7 @@ dependencies = [ "httparse", "httpdate", "itoa", - "pin-project", + "pin-project-lite", "socket2", "tokio", "tower-service", @@ -1601,9 +1602,9 @@ dependencies = [ [[package]] name = "k256" -version = "0.9.2" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "981d961c83e235370a70e302f16ecbfd34df72a14c5c0973d937f5fa26248653" +checksum = "f3a26a4a8e8b0ab315c687767b543c923c9667a1f2bf42a42818d1453891c7c1" dependencies = [ "cfg-if 1.0.0", "ecdsa", @@ -1638,9 +1639,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.95" +version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "789da6d93f1b866ffe175afc5322a4d76c038605a1c3319bb57b06967ca98a36" +checksum = "12b8adadd720df158f4d70dfe7ccc6adb0472d7c55ca83445f6a5ab3e36f8fb6" [[package]] name = "lock_api" @@ -1692,9 +1693,9 @@ checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" [[package]] name = "memchr" -version = "2.4.0" +version = "2.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc" +checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" [[package]] name = "memoffset" @@ -1744,9 +1745,9 @@ dependencies = [ [[package]] name = "mio" -version = "0.7.11" +version = "0.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf80d3e903b34e0bd7282b218398aec54e082c840d9baf8339e0080a0c542956" +checksum = "8c2bdb6314ec10835cd3293dd268473a835c02b7b352e788be788b3c6ca6bb16" dependencies = [ "libc", "log 0.4.14", @@ -1816,9 +1817,9 @@ dependencies = [ [[package]] name = "nom" -version = "6.1.2" +version = "6.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7413f999671bd4745a7b624bd370a569fb6bc574b23c83a3c5ed2e453f3d5e2" +checksum = "9c5c51b9083a3c620fa67a2a635d1ce7d95b897e957d6b28ff9a5da960a103a6" dependencies = [ "bitvec", "funty", @@ -1944,9 +1945,9 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "openssl" -version = "0.10.34" +version = "0.10.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d7830286ad6a3973c0f1d9b73738f69c76b739301d0229c4b96501695cbe4c8" +checksum = "549430950c79ae24e6d02e0b7404534ecf311d94cc9f861e9e4020187d13d885" dependencies = [ "bitflags", "cfg-if 1.0.0", @@ -1964,9 +1965,9 @@ checksum = "28988d872ab76095a6e6ac88d99b54fd267702734fd7ffe610ca27f533ddb95a" [[package]] name = "openssl-sys" -version = "0.9.63" +version = "0.9.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6b0d6fb7d80f877617dfcb014e605e2b5ab2fb0afdf27935219bb6bd984cb98" +checksum = "7a7907e3bfa08bb85105209cdfcb6c63d109f8f6c1ed6ca318fff5c1853fbc1d" dependencies = [ "autocfg 1.0.1", "cc", @@ -1990,7 +1991,7 @@ dependencies = [ "lazy_static", "percent-encoding", "pin-project", - "rand 0.8.3", + "rand 0.8.4", "thiserror", ] @@ -2040,7 +2041,7 @@ dependencies = [ "cfg-if 1.0.0", "instant", "libc", - "redox_syscall 0.2.8", + "redox_syscall 0.2.9", "smallvec 1.6.1", "winapi", ] @@ -2248,9 +2249,9 @@ dependencies = [ [[package]] name = "protobuf" -version = "2.23.0" +version = "2.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45604fc7a88158e7d514d8e22e14ac746081e7a70d7690074dd0029ee37458d6" +checksum = "db50e77ae196458ccd3dc58a31ea1a90b0698ab1b7928d89f644c25d72070267" [[package]] name = "quick-error" @@ -2307,14 +2308,14 @@ dependencies = [ [[package]] name = "rand" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e" +checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" dependencies = [ "libc", - "rand_chacha 0.3.0", - "rand_core 0.6.2", - "rand_hc 0.3.0", + "rand_chacha 0.3.1", + "rand_core 0.6.3", + "rand_hc 0.3.1", ] [[package]] @@ -2339,12 +2340,12 @@ dependencies = [ [[package]] name = "rand_chacha" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core 0.6.2", + "rand_core 0.6.3", ] [[package]] @@ -2373,9 +2374,9 @@ dependencies = [ [[package]] name = "rand_core" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7" +checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" dependencies = [ "getrandom 0.2.3", ] @@ -2400,11 +2401,11 @@ dependencies = [ [[package]] name = "rand_hc" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73" +checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" dependencies = [ - "rand_core 0.6.2", + "rand_core 0.6.3", ] [[package]] @@ -2477,9 +2478,9 @@ checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" [[package]] name = "redox_syscall" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "742739e41cd49414de871ea5e549afb7e2a3ac77b589bcbebe8c82fab37147fc" +checksum = "5ab49abadf3f9e1c4bc499e8845e152ad87d2ad2d30371841171169e9d75feee" dependencies = [ "bitflags", ] @@ -2502,14 +2503,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64" dependencies = [ "getrandom 0.2.3", - "redox_syscall 0.2.8", + "redox_syscall 0.2.9", ] [[package]] name = "regex" -version = "1.5.4" +version = "1.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" +checksum = "2a26af418b574bd56588335b3a3659a65725d4e636eb1016c2f9e3b38c7cc759" dependencies = [ "aho-corasick", "memchr", @@ -2612,9 +2613,9 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.19" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "410f7acf3cb3a44527c5d9546bad4bf4e6c460915d5f9f2fc524498bfe8f70ce" +checksum = "dead70b0b5e03e9c814bcb6b01e03e68f7c57a80aa48c72ec92152ab3e818d49" [[package]] name = "rustc-hash" @@ -2696,9 +2697,9 @@ dependencies = [ [[package]] name = "secp256k1" -version = "0.20.2" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee5070fdc6f26ca5be6dcfc3d07c76fdb974a63a8b246b459854274145f5a258" +checksum = "97d03ceae636d0fed5bae6a7f4f664354c5f4fcedf6eef053fef17e49f837d0a" dependencies = [ "secp256k1-sys", "serde", @@ -2706,9 +2707,9 @@ dependencies = [ [[package]] name = "secp256k1-sys" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67e4b6455ee49f5901c8985b88f98fb0a0e1d90a6661f5a03f4888bd987dad29" +checksum = "827cb7cce42533829c792fc51b82fbf18b125b45a702ef2c8be77fce65463a7b" dependencies = [ "cc", ] @@ -2725,9 +2726,9 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.2.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3670b1d2fdf6084d192bc71ead7aabe6c06aa2ea3fbd9cc3ac111fa5c2b1bd84" +checksum = "23a2ac85147a3a11d77ecf1bc7166ec0b92febfa4461c37944e180f319ece467" dependencies = [ "bitflags", "core-foundation", @@ -2738,9 +2739,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3676258fd3cfe2c9a0ec99ce3038798d847ce3e4bb17746373eb9f0f1ac16339" +checksum = "7e4effb91b4b8b6fb7732e670b6cee160278ff8e6bf485c7805d9e319d76e284" dependencies = [ "core-foundation-sys", "libc", @@ -2924,7 +2925,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0f0242b8e50dd9accdd56170e94ca1ebd223b098eb9c83539a6e367d0f36ae68" dependencies = [ "digest", - "rand_core 0.6.2", + "rand_core 0.6.3", ] [[package]] @@ -3042,9 +3043,9 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.72" +version = "1.0.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1e8cdbefb79a9a5a65e0db8b47b723ee907b7c7f8496c76a1770b5c310bab82" +checksum = "f71489ff30030d2ae598524f61326b902466f72a0fb1a8564c001cc63425bcc7" dependencies = [ "proc-macro2", "quote", @@ -3077,17 +3078,17 @@ checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22" dependencies = [ "cfg-if 1.0.0", "libc", - "rand 0.8.3", - "redox_syscall 0.2.8", + "rand 0.8.4", + "redox_syscall 0.2.9", "remove_dir_all", "winapi", ] [[package]] name = "tendermint" -version = "0.19.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "831486f28e65c6f6c6f8afb067796f3c470db91a44d177224f8e6287601391b6" +checksum = "e7d330f5d92e5e1c7a84130805b48b4983d98a37257034544492e3566315142b" dependencies = [ "anomaly", "async-trait", @@ -3095,7 +3096,6 @@ dependencies = [ "chrono", "ed25519", "ed25519-dalek", - "funty", "futures", "num-traits", "once_cell", @@ -3118,9 +3118,9 @@ dependencies = [ [[package]] name = "tendermint-light-client" -version = "0.19.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ed9969bedd65d67f5bdee95fcde4a8e54ba11b3eebb2bfcf24a0d8abb0e10ea" +checksum = "c8809a07c5f1a400a1ce49bb6473a713f059511db4201f0f810ea4614665a212" dependencies = [ "anomaly", "contracts", @@ -3140,9 +3140,9 @@ dependencies = [ [[package]] name = "tendermint-proto" -version = "0.19.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32bbc1bc55f09de4d00b5d69aa6b60392ba37c5e4761d869f76065d352bd3360" +checksum = "fadcaea1eecd91dbdd9636fe8ad38d2b41fc0ae814c176e51e00925cdda78a34" dependencies = [ "anomaly", "bytes", @@ -3159,9 +3159,9 @@ dependencies = [ [[package]] name = "tendermint-rpc" -version = "0.19.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5379de699d14c3edcddc2d9f30ae42066942b9b88aa81b88f047e4e867680fc5" +checksum = "d8f1c168b05be5e5c4237f49584356432defc91903f9dd7dbe74798eda48db43" dependencies = [ "async-trait", "async-tungstenite", @@ -3190,9 +3190,9 @@ dependencies = [ [[package]] name = "tendermint-testgen" -version = "0.19.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bc19930d52024c6c061071a10f92caec0cb6416067e39264c6553eb6c6147f8" +checksum = "cbe4acaa8aa91bb208a22a7aa3e57610e2f6948c0b69667f7666ebc1bec27171" dependencies = [ "ed25519-dalek", "gumdrop 0.8.0", @@ -3340,9 +3340,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "1.6.1" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a38d31d7831c6ed7aad00aa4c12d9375fd225a6dd77da1d25b707346319a975" +checksum = "5fb2ed024293bb19f7a5dc54fe83bf86532a44c12a2bb8ba40d64a4509395ca2" dependencies = [ "autocfg 1.0.1", "bytes", @@ -3465,7 +3465,7 @@ dependencies = [ "futures-util", "indexmap", "pin-project", - "rand 0.8.3", + "rand 0.8.4", "slab", "tokio", "tokio-stream", @@ -3609,7 +3609,7 @@ dependencies = [ "httparse", "input_buffer", "log 0.4.14", - "rand 0.8.3", + "rand 0.8.4", "sha-1", "url", "utf-8", @@ -3650,9 +3650,9 @@ dependencies = [ [[package]] name = "unicode-normalization" -version = "0.1.18" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33717dca7ac877f497014e10d73f3acf948c342bee31b5ca7892faf94ccc6b49" +checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9" dependencies = [ "tinyvec", ] @@ -3707,9 +3707,9 @@ checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" [[package]] name = "vcpkg" -version = "0.2.13" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "025ce40a007e1907e58d5bc1a594def78e5573bb0b1160bc389634e8f12e4faa" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] name = "vec_map" diff --git a/modules/Cargo.toml b/modules/Cargo.toml index 0e46f0c338..42ef1ef318 100644 --- a/modules/Cargo.toml +++ b/modules/Cargo.toml @@ -38,13 +38,13 @@ subtle-encoding = "0.5" sha2 = { version = "0.9.3", optional = true } [dependencies.tendermint] -version = "=0.19.0" +version = "=0.20.0" [dependencies.tendermint-proto] -version = "=0.19.0" +version = "=0.20.0" [dependencies.tendermint-testgen] -version = "=0.19.0" +version = "=0.20.0" optional = true [dev-dependencies] @@ -52,8 +52,8 @@ env_logger = "0.8.4" tracing-subscriber = "0.2.18" test-env-log = { version = "0.2.7", features = ["trace"] } modelator = { git = "https://github.com/informalsystems/modelator", rev = "99f656fa8b3cf46a2aa0b6513e4e140d1778c4bd" } -tendermint-rpc = { version = "=0.19.0", features = ["http-client", "websocket-client"] } -tendermint-testgen = { version = "=0.19.0" } # Needed for generating (synthetic) light blocks. +tendermint-rpc = { version = "=0.20.0", features = ["http-client", "websocket-client"] } +tendermint-testgen = { version = "=0.20.0" } # Needed for generating (synthetic) light blocks. sha2 = { version = "0.9.3" } [[test]] diff --git a/proto/Cargo.toml b/proto/Cargo.toml index 9de10d20d9..390b505a34 100644 --- a/proto/Cargo.toml +++ b/proto/Cargo.toml @@ -30,4 +30,4 @@ thiserror = "1.0" tonic = "0.4" [dependencies.tendermint-proto] -version = "=0.19.0" +version = "=0.20.0" diff --git a/relayer-cli/Cargo.toml b/relayer-cli/Cargo.toml index 8f1b6014f1..ee6d760ec9 100644 --- a/relayer-cli/Cargo.toml +++ b/relayer-cli/Cargo.toml @@ -49,17 +49,17 @@ itertools = "0.10.1" atty = "0.2.14" [dependencies.tendermint-proto] -version = "=0.19.0" +version = "=0.20.0" [dependencies.tendermint] -version = "=0.19.0" +version = "=0.20.0" [dependencies.tendermint-rpc] -version = "=0.19.0" +version = "=0.20.0" features = ["http-client", "websocket-client"] [dependencies.tendermint-light-client] -version = "=0.19.0" +version = "=0.20.0" features = ["unstable"] [dependencies.abscissa_core] diff --git a/relayer/Cargo.toml b/relayer/Cargo.toml index 389d91cb2e..bf715b5655 100644 --- a/relayer/Cargo.toml +++ b/relayer/Cargo.toml @@ -57,18 +57,18 @@ async-stream = "0.3.2" fraction = {version = "0.8.0", default-features = false } [dependencies.tendermint] -version = "=0.19.0" +version = "=0.20.0" [dependencies.tendermint-rpc] -version = "=0.19.0" +version = "=0.20.0" features = ["http-client", "websocket-client"] [dependencies.tendermint-light-client] -version = "=0.19.0" +version = "=0.20.0" features = ["unstable"] [dependencies.tendermint-proto] -version = "=0.19.0" +version = "=0.20.0" [dev-dependencies] ibc = { version = "0.5.0", path = "../modules", features = ["mocks"] } @@ -78,4 +78,4 @@ tracing-subscriber = "0.2.18" test-env-log = { version = "0.2.7", features = ["trace"] } # Needed for generating (synthetic) light blocks. -tendermint-testgen = { version = "=0.19.0" } +tendermint-testgen = { version = "=0.20.0" } diff --git a/relayer/src/chain/cosmos.rs b/relayer/src/chain/cosmos.rs index 1813f3cd2a..b3431768da 100644 --- a/relayer/src/chain/cosmos.rs +++ b/relayer/src/chain/cosmos.rs @@ -19,7 +19,7 @@ use tendermint::block::Height; use tendermint::consensus::Params; use tendermint_light_client::types::LightBlock as TMLightBlock; use tendermint_proto::Protobuf; -use tendermint_rpc::endpoint::tx_search::ResultTx; +use tendermint_rpc::endpoint::tx::Response as ResultTx; use tendermint_rpc::query::Query; use tendermint_rpc::{endpoint::broadcast::tx_sync::Response, Client, HttpClient, Order}; use tokio::runtime::Runtime as TokioRuntime; From 33fe434568b171db4679b89bda4c5e7e1af7ae0f Mon Sep 17 00:00:00 2001 From: Romain Ruetschi Date: Thu, 24 Jun 2021 12:29:19 +0200 Subject: [PATCH 18/32] Update changelog --- CHANGELOG.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c9960105c4..6b8c095799 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,12 @@ ## Unreleased -> Nothing yet. +### IMPROVEMENTS + +- Update to `tendermint-rs` v0.19.0 ([#1125]) + +[#1125]: https://github.com/informalsystems/ibc-rs/issues/1125 + ## v0.5.0 *June 22nd, 2021* From 4b3e46c90975e3221f9c3d9329450e4713f37a89 Mon Sep 17 00:00:00 2001 From: Romain Ruetschi Date: Thu, 24 Jun 2021 13:33:43 +0200 Subject: [PATCH 19/32] Fix tendermint-rs version in changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b8c095799..d980f575cc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ ### IMPROVEMENTS -- Update to `tendermint-rs` v0.19.0 ([#1125]) +- Update to `tendermint-rs` v0.20.0 ([#1125]) [#1125]: https://github.com/informalsystems/ibc-rs/issues/1125 From cff89a8a0b7d07899353993723cf29c3474e88aa Mon Sep 17 00:00:00 2001 From: cezarad Date: Wed, 30 Jun 2021 16:36:21 +0200 Subject: [PATCH 20/32] Update predicates.rs --- modules/src/ics07_tendermint/predicates.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/src/ics07_tendermint/predicates.rs b/modules/src/ics07_tendermint/predicates.rs index aaf4659d82..6e8c65e7e9 100644 --- a/modules/src/ics07_tendermint/predicates.rs +++ b/modules/src/ics07_tendermint/predicates.rs @@ -153,7 +153,7 @@ impl Predicates { .validators() .iter() .fold(0u64, |total, val_info| { - total + val_info.voting_power.value() + total + val_info.power.value() }) } } From 4f47dcfd6d286c87c6673482758d3b44f0c666ff Mon Sep 17 00:00:00 2001 From: cezarad Date: Mon, 5 Jul 2021 13:43:46 +0200 Subject: [PATCH 21/32] Update context.rs --- modules/src/mock/context.rs | 83 ++++++++++++++++++++++++++++++++++++- 1 file changed, 82 insertions(+), 1 deletion(-) diff --git a/modules/src/mock/context.rs b/modules/src/mock/context.rs index e69b80a380..828c0f9f18 100644 --- a/modules/src/mock/context.rs +++ b/modules/src/mock/context.rs @@ -241,6 +241,72 @@ impl MockContext { self } + pub fn with_client_parametrized_history( + mut self, + client_id: &ClientId, + client_state_height: Height, + client_type: Option, + consensus_state_height: Option, + ) -> Self { + let cs_height = consensus_state_height.unwrap_or(client_state_height); + let prev_cs_height = cs_height.clone().sub(1).unwrap_or(client_state_height); + + let client_type = client_type.unwrap_or(ClientType::Mock); + + let (client_state, consensus_state) = match client_type { + // If it's a mock client, create the corresponding mock states. + ClientType::Mock => ( + Some(MockClientState(MockHeader::new(client_state_height)).into()), + MockConsensusState(MockHeader::new(cs_height)).into(), + ), + // If it's a Tendermint client, we need TM states. + ClientType::Tendermint => { + let light_block = HostBlock::generate_tm_block( + self.host_chain_id.clone(), + cs_height.revision_height, + ); + + let consensus_state = AnyConsensusState::from(light_block.clone()); + let client_state = + get_dummy_tendermint_client_state(light_block.signed_header.header); + + // Return the tuple. + (Some(client_state), consensus_state) + } + }; + + let prev_consensus_state = match client_type { + // If it's a mock client, create the corresponding mock states. + ClientType::Mock => MockConsensusState(MockHeader::new(prev_cs_height)).into(), + // If it's a Tendermint client, we need TM states. + ClientType::Tendermint => { + let light_block = HostBlock::generate_tm_block( + self.host_chain_id.clone(), + prev_cs_height.revision_height, + ); + AnyConsensusState::from(light_block) + } + }; + + let consensus_states = vec![ + (prev_cs_height, prev_consensus_state), + (cs_height, consensus_state), + ] + .into_iter() + .collect(); + + info!("Consensus state {:?}", consensus_states); + + let client_record = MockClientRecord { + client_type, + client_state, + consensus_states, + }; + + self.clients.insert(client_id.clone(), client_record); + self + } + /// Associates a connection to this context. pub fn with_connection( mut self, @@ -351,7 +417,7 @@ impl MockContext { /// Accessor for a block of the local (host) chain from this context. /// Returns `None` if the block at the requested height does not exist. - fn host_block(&self, target_height: Height) -> Option<&HostBlock> { + pub fn host_block(&self, target_height: Height) -> Option<&HostBlock> { let target = target_height.revision_height as usize; let latest = self.latest_height.revision_height as usize; @@ -435,6 +501,21 @@ impl MockContext { }) .collect() } + + pub fn latest_client_states(&self, client_id: &ClientId) -> &AnyClientState { + self.clients[client_id].client_state.as_ref().unwrap() + } + + pub fn latest_consensus_states( + &self, + client_id: &ClientId, + height: &Height, + ) -> &AnyConsensusState { + self.clients[client_id] + .consensus_states + .get(height) + .unwrap() + } } impl Ics26Context for MockContext {} From bc72d525edfd1c91b7236172fc97b817d25cc38a Mon Sep 17 00:00:00 2001 From: cezarad Date: Mon, 5 Jul 2021 13:46:43 +0200 Subject: [PATCH 22/32] tests --- .../src/ics02_client/handler/update_client.rs | 368 +++++++++++++++++- modules/src/ics07_tendermint/client_def.rs | 11 + modules/src/ics07_tendermint/predicates.rs | 1 - 3 files changed, 376 insertions(+), 4 deletions(-) diff --git a/modules/src/ics02_client/handler/update_client.rs b/modules/src/ics02_client/handler/update_client.rs index d85c163077..6e220c214b 100644 --- a/modules/src/ics02_client/handler/update_client.rs +++ b/modules/src/ics02_client/handler/update_client.rs @@ -107,17 +107,21 @@ mod tests { use crate::events::IbcEvent; use crate::handler::HandlerOutput; - use crate::ics02_client::client_state::AnyClientState; + use crate::ics02_client::client_consensus::AnyConsensusState; + use crate::ics02_client::client_state::{AnyClientState, ClientState}; + use crate::ics02_client::client_type::ClientType; use crate::ics02_client::error::Kind; use crate::ics02_client::handler::dispatch; use crate::ics02_client::handler::ClientResult::Update; - use crate::ics02_client::header::Header; + use crate::ics02_client::header::{AnyHeader, Header}; use crate::ics02_client::msgs::update_client::MsgUpdateAnyClient; use crate::ics02_client::msgs::ClientMsg; - use crate::ics24_host::identifier::ClientId; + + use crate::ics24_host::identifier::{ChainId, ClientId}; use crate::mock::client_state::MockClientState; use crate::mock::context::MockContext; use crate::mock::header::MockHeader; + use crate::mock::host::{HostBlock, HostType}; use crate::test_utils::get_dummy_account_id; use crate::timestamp::Timestamp; use crate::Height; @@ -241,4 +245,362 @@ mod tests { } } } + + #[test] + fn test_update_syntetic_tendermint_client_adjacent_ok() { + let client_id = ClientId::new(ClientType::Tendermint, 0).unwrap(); + let client_height = Height::new(1, 20); + let update_height = Height::new(1, 21); + + let ctx = MockContext::new( + ChainId::new("mockgaiaA".to_string(), 1), + HostType::Mock, + 5, + Height::new(1, 1), + ) + .with_client_parametrized( + &client_id, + client_height, + Some(ClientType::Tendermint), // The target host chain (B) is synthetic TM. + Some(client_height), + ); + + let ctx_b = MockContext::new( + ChainId::new("mockgaiaB".to_string(), 1), + HostType::SyntheticTendermint, + 5, + update_height, + ); + + let signer = get_dummy_account_id(); + + let block_ref = ctx_b.host_block(update_height); + let mut latest_header: AnyHeader = block_ref.cloned().map(Into::into).unwrap(); + + latest_header = match latest_header { + AnyHeader::Tendermint(mut theader) => { + theader.trusted_height = client_height; + AnyHeader::Tendermint(theader) + } + AnyHeader::Mock(m) => AnyHeader::Mock(m), + }; + + let msg = MsgUpdateAnyClient { + client_id: client_id.clone(), + header: latest_header, + signer, + }; + + let output = dispatch(&ctx, ClientMsg::UpdateClient(msg.clone())); + + match output { + Ok(HandlerOutput { + result, + mut events, + log, + }) => { + assert_eq!(events.len(), 1); + let event = events.pop().unwrap(); + assert!( + matches!(event, IbcEvent::UpdateClient(e) if e.client_id() == &msg.client_id) + ); + assert!(log.is_empty()); + // Check the result + match result { + Update(upd_res) => { + assert_eq!(upd_res.client_id, client_id); + assert_eq!(upd_res.client_state.is_frozen(), false); + assert_eq!(upd_res.client_state.latest_height(), msg.header.height(),) + } + _ => panic!("update handler result has incorrect type"), + } + } + Err(err) => { + panic!("unexpected error: {}", err); + } + } + } + + #[test] + fn test_update_syntetic_tendermint_client_non_adjacent_ok() { + let client_id = ClientId::new(ClientType::Tendermint, 0).unwrap(); + let client_height = Height::new(1, 20); + let update_height = Height::new(1, 21); + + let ctx = MockContext::new( + ChainId::new("mockgaiaA".to_string(), 1), + HostType::Mock, + 5, + Height::new(1, 1), + ) + .with_client_parametrized_history( + &client_id, + client_height, + Some(ClientType::Tendermint), // The target host chain (B) is synthetic TM. + Some(client_height), + ); + + let ctx_b = MockContext::new( + ChainId::new("mockgaiaB".to_string(), 1), + HostType::SyntheticTendermint, + 5, + update_height, + ); + + let signer = get_dummy_account_id(); + + let block_ref = ctx_b.host_block(update_height); + let mut latest_header: AnyHeader = block_ref.cloned().map(Into::into).unwrap(); + + let trusted_height = client_height.clone().sub(1).unwrap_or_default(); + + latest_header = match latest_header { + AnyHeader::Tendermint(mut theader) => { + theader.trusted_height = trusted_height; + AnyHeader::Tendermint(theader) + } + AnyHeader::Mock(m) => AnyHeader::Mock(m), + }; + + let msg = MsgUpdateAnyClient { + client_id: client_id.clone(), + header: latest_header, + signer, + }; + + let output = dispatch(&ctx, ClientMsg::UpdateClient(msg.clone())); + + match output { + Ok(HandlerOutput { + result, + mut events, + log, + }) => { + assert_eq!(events.len(), 1); + let event = events.pop().unwrap(); + assert!( + matches!(event, IbcEvent::UpdateClient(e) if e.client_id() == &msg.client_id) + ); + assert!(log.is_empty()); + // Check the result + match result { + Update(upd_res) => { + assert_eq!(upd_res.client_id, client_id); + assert_eq!(upd_res.client_state.is_frozen(), false); + assert_eq!(upd_res.client_state.latest_height(), msg.header.height(),) + } + _ => panic!("update handler result has incorrect type"), + } + } + Err(err) => { + panic!("unexpected error: {}", err); + } + } + } + + #[test] + fn test_update_syntetic_tendermint_client_duplicate_ok() { + let client_id = ClientId::new(ClientType::Tendermint, 0).unwrap(); + let client_height = Height::new(1, 20); + + let chain_start_height = Height::new(1, 11); + + let ctx = MockContext::new( + ChainId::new("mockgaiaA".to_string(), 1), + HostType::Mock, + 5, + chain_start_height, + ) + .with_client_parametrized( + &client_id, + client_height, + Some(ClientType::Tendermint), // The target host chain (B) is synthetic TM. + Some(client_height), + ); + + let ctx_b = MockContext::new( + ChainId::new("mockgaiaB".to_string(), 1), + HostType::SyntheticTendermint, + 5, + client_height, + ); + + let signer = get_dummy_account_id(); + + let block_ref = ctx_b.host_block(client_height); + let latest_header: AnyHeader = match block_ref.cloned().map(Into::into).unwrap() { + AnyHeader::Tendermint(mut theader) => { + let cons_state = ctx + .latest_consensus_states(&client_id, &client_height) + .clone(); + if let AnyConsensusState::Tendermint(tcs) = cons_state { + theader.signed_header.header.time = tcs.timestamp; + } + AnyHeader::Tendermint(theader) + } + AnyHeader::Mock(header) => AnyHeader::Mock(header), + }; + + let msg = MsgUpdateAnyClient { + client_id: client_id.clone(), + header: latest_header, + signer, + }; + + let output = dispatch(&ctx, ClientMsg::UpdateClient(msg.clone())); + + match output { + Ok(HandlerOutput { + result, + mut events, + log, + }) => { + assert_eq!(events.len(), 1); + let event = events.pop().unwrap(); + assert!( + matches!(event, IbcEvent::UpdateClient(e) if e.client_id() == &msg.client_id) + ); + assert!(log.is_empty()); + // Check the result + match result { + Update(upd_res) => { + assert_eq!(upd_res.client_id, client_id); + assert_eq!(upd_res.client_state.is_frozen(), false); + assert_eq!( + upd_res.client_state, + ctx.latest_client_states(&client_id).clone() + ); + assert_eq!(upd_res.client_state.latest_height(), msg.header.height(),) + } + _ => panic!("update handler result has incorrect type"), + } + } + Err(_err) => { + panic!("unexpected error"); + } + } + } + + #[test] + fn test_update_syntetic_tendermint_client_duplicate_height_frozen() { + let client_id = ClientId::new(ClientType::Tendermint, 0).unwrap(); + let client_height = Height::new(1, 20); + + let chain_start_height = Height::new(1, 11); + + let ctx = MockContext::new( + ChainId::new("mockgaiaA".to_string(), 1), + HostType::Mock, + 5, + chain_start_height, + ) + .with_client_parametrized( + &client_id, + client_height, + Some(ClientType::Tendermint), // The target host chain (B) is synthetic TM. + Some(client_height), + ); + + let signer = get_dummy_account_id(); + + let block_ref = HostBlock::generate_block( + ChainId::new("mockgaiaB".to_string(), 1), + HostType::SyntheticTendermint, + client_height.revision_height, + ); + + let latest_header: AnyHeader = Some(block_ref).map(Into::into).unwrap(); + + let msg = MsgUpdateAnyClient { + client_id: client_id.clone(), + header: latest_header, + signer, + }; + + let output = dispatch(&ctx, ClientMsg::UpdateClient(msg.clone())); + + match output { + Ok(HandlerOutput { + result, + mut events, + log, + }) => { + assert_eq!(events.len(), 1); + let event = events.pop().unwrap(); + assert!( + matches!(event, IbcEvent::UpdateClient(e) if e.client_id() == &msg.client_id) + ); + assert!(log.is_empty()); + // Check the result + match result { + Update(upd_res) => { + assert_eq!(upd_res.client_id, client_id); + assert_eq!(upd_res.client_state.is_frozen(), true); + assert_ne!( + upd_res.client_state, + ctx.latest_client_states(&client_id).clone() + ); + assert_eq!(upd_res.client_state.latest_height(), msg.header.height(),) + } + _ => panic!("update handler result has incorrect type"), + } + } + Err(_err) => { + panic!("unexpected error"); + } + } + } + + #[test] + fn test_update_syntetic_tendermint_client_lower_height() { + let client_id = ClientId::new(ClientType::Tendermint, 0).unwrap(); + let client_height = Height::new(1, 20); + + let client_update_height = Height::new(1, 19); + + let chain_start_height = Height::new(1, 11); + + let ctx = MockContext::new( + ChainId::new("mockgaiaA".to_string(), 1), + HostType::Mock, + 5, + chain_start_height, + ) + .with_client_parametrized( + &client_id, + client_height, + Some(ClientType::Tendermint), // The target host chain (B) is synthetic TM. + Some(client_height), + ); + + let ctx_b = MockContext::new( + ChainId::new("mockgaiaB".to_string(), 1), + HostType::SyntheticTendermint, + 5, + client_height, + ); + + let signer = get_dummy_account_id(); + + let block_ref = ctx_b.host_block(client_update_height); + let latest_header: AnyHeader = block_ref.cloned().map(Into::into).unwrap(); + + let msg = MsgUpdateAnyClient { + client_id, + header: latest_header, + signer, + }; + + let output = dispatch(&ctx, ClientMsg::UpdateClient(msg)); + + match output { + Ok(_) => { + panic!("update handler result has incorrect type"); + } + Err(err) => { + assert_eq!(err.kind(), &Kind::HeaderVerificationFailure); + println!("err is {}", err.to_string()); + } + } + } } diff --git a/modules/src/ics07_tendermint/client_def.rs b/modules/src/ics07_tendermint/client_def.rs index 220c983762..1aaa15c363 100644 --- a/modules/src/ics07_tendermint/client_def.rs +++ b/modules/src/ics07_tendermint/client_def.rs @@ -40,6 +40,10 @@ impl ClientDef for TendermintClient { ) -> Result<(Self::ClientState, Self::ConsensusState), Box> { // check if a consensus state is already installed; if so it should // match the untrusted header. + + //TODO remove: + // let time = header.signed_header.header.time; + if let Some(cs) = ctx.consensus_state(&client_id, header.height()) { //could the header height be zero ? let consensus_state = downcast!( @@ -47,14 +51,21 @@ impl ClientDef for TendermintClient { ) .ok_or_else(|| Kind::ClientArgsTypeMismatch(ClientType::Tendermint))?; + // //TODO remove: + // header.signed_header.header.time = consensus_state.timestamp; + if consensus_state != ConsensusState::from(header.clone()) { //freeze the client and return the installed consensus state return Ok(( client_state.with_set_frozen(header.height()), consensus_state, )); + } else { + return Ok((client_state, consensus_state)); } }; + // //TODO remove: + // header.signed_header.header.time = time; let latest_consensus_state = match ctx.consensus_state(&client_id, client_state.latest_height) { diff --git a/modules/src/ics07_tendermint/predicates.rs b/modules/src/ics07_tendermint/predicates.rs index aaf4659d82..8d1c13445e 100644 --- a/modules/src/ics07_tendermint/predicates.rs +++ b/modules/src/ics07_tendermint/predicates.rs @@ -13,7 +13,6 @@ use tendermint::trust_threshold::TrustThresholdFraction; use tendermint::validator::Set as ValidatorSet; use tendermint::vote::{SignedVote, ValidatorIndex, Vote}; - #[derive(Copy, Clone, Debug, Default)] pub struct Predicates; From 98f5cb0ba6b174b07cf74ac7cd06ef2a01118a03 Mon Sep 17 00:00:00 2001 From: cezarad Date: Mon, 5 Jul 2021 13:52:01 +0200 Subject: [PATCH 23/32] tendermint stuff in --- modules/src/ics07_tendermint/header.rs | 2 +- modules/src/test_utils.rs | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/src/ics07_tendermint/header.rs b/modules/src/ics07_tendermint/header.rs index e342cdebfa..9f041fb0b6 100644 --- a/modules/src/ics07_tendermint/header.rs +++ b/modules/src/ics07_tendermint/header.rs @@ -191,7 +191,7 @@ pub mod test_util { 281_815_u64.try_into().unwrap(), ); - let vs = ValidatorSet::new(vec![v1], Some(v1)); + let vs = ValidatorSet::new(vec![v1.clone()], Some(v1)); Header { signed_header: shdr, diff --git a/modules/src/test_utils.rs b/modules/src/test_utils.rs index 87eceb365f..92da4801a8 100644 --- a/modules/src/test_utils.rs +++ b/modules/src/test_utils.rs @@ -9,7 +9,8 @@ pub fn default_consensus_params() -> consensus::Params { consensus::Params { block: block::Size { max_bytes: 22020096, - max_gas: -1, // Tendetmint-go also has TimeIotaMs: 1000, // 1s + max_gas: -1, // Tendetmint-go also has + time_iota_ms: 1000, // 1s }, evidence: evidence::Params { max_age_num_blocks: 100000, From e1a0f1b75c351cb222089fe55d45ae0b01471e5c Mon Sep 17 00:00:00 2001 From: cezarad <9439384+cezarad@users.noreply.github.com> Date: Mon, 5 Jul 2021 20:05:51 +0200 Subject: [PATCH 24/32] Update Cargo.toml --- Cargo.toml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index af0583a47a..6557fa2729 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,8 +13,8 @@ exclude = [ ] [patch.crates-io] -tendermint = { path = "../tendermint-rs/tendermint" } -tendermint-rpc = { path = "../tendermint-rs/rpc" } -tendermint-proto = { path = "../tendermint-rs/proto" } -tendermint-light-client = { path = "../tendermint-rs/light-client" } -tendermint-testgen = { path = "../tendermint-rs/testgen" } + tendermint = { git = "https://github.com/informalsystems/tendermint-rs", branch = "master" } + tendermint-rpc = { git = "https://github.com/informalsystems/tendermint-rs", branch = "master" } + tendermint-proto = { git = "https://github.com/informalsystems/tendermint-rs", branch = "master" } + tendermint-light-client = { git = "https://github.com/informalsystems/tendermint-rs", branch = "master" } + tendermint-testgen = { git = "https://github.com/informalsystems/tendermint-rs", branch = "master" } From fd7bc2ed77c18e493524a7a4bb27a387611f9bdb Mon Sep 17 00:00:00 2001 From: cezarad Date: Tue, 6 Jul 2021 10:44:47 +0200 Subject: [PATCH 25/32] clippy + fmt --- modules/src/ics02_client/handler/update_client.rs | 8 ++++---- modules/src/ics07_tendermint/predicates.rs | 4 +--- modules/src/test_utils.rs | 2 +- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/modules/src/ics02_client/handler/update_client.rs b/modules/src/ics02_client/handler/update_client.rs index 6e220c214b..52e9f1b5f3 100644 --- a/modules/src/ics02_client/handler/update_client.rs +++ b/modules/src/ics02_client/handler/update_client.rs @@ -309,7 +309,7 @@ mod tests { match result { Update(upd_res) => { assert_eq!(upd_res.client_id, client_id); - assert_eq!(upd_res.client_state.is_frozen(), false); + assert!(!upd_res.client_state.is_frozen()); assert_eq!(upd_res.client_state.latest_height(), msg.header.height(),) } _ => panic!("update handler result has incorrect type"), @@ -386,7 +386,7 @@ mod tests { match result { Update(upd_res) => { assert_eq!(upd_res.client_id, client_id); - assert_eq!(upd_res.client_state.is_frozen(), false); + assert!(upd_res.client_state.is_frozen()); assert_eq!(upd_res.client_state.latest_height(), msg.header.height(),) } _ => panic!("update handler result has incorrect type"), @@ -465,7 +465,7 @@ mod tests { match result { Update(upd_res) => { assert_eq!(upd_res.client_id, client_id); - assert_eq!(upd_res.client_state.is_frozen(), false); + assert!(!upd_res.client_state.is_frozen()); assert_eq!( upd_res.client_state, ctx.latest_client_states(&client_id).clone() @@ -535,7 +535,7 @@ mod tests { match result { Update(upd_res) => { assert_eq!(upd_res.client_id, client_id); - assert_eq!(upd_res.client_state.is_frozen(), true); + assert!(upd_res.client_state.is_frozen()); assert_ne!( upd_res.client_state, ctx.latest_client_states(&client_id).clone() diff --git a/modules/src/ics07_tendermint/predicates.rs b/modules/src/ics07_tendermint/predicates.rs index c8d2ebe8d2..bc46b567dd 100644 --- a/modules/src/ics07_tendermint/predicates.rs +++ b/modules/src/ics07_tendermint/predicates.rs @@ -151,9 +151,7 @@ impl Predicates { validator_set .validators() .iter() - .fold(0u64, |total, val_info| { - total + val_info.power.value() - }) + .fold(0u64, |total, val_info| total + val_info.power.value()) } } diff --git a/modules/src/test_utils.rs b/modules/src/test_utils.rs index 92da4801a8..5943a4e817 100644 --- a/modules/src/test_utils.rs +++ b/modules/src/test_utils.rs @@ -9,7 +9,7 @@ pub fn default_consensus_params() -> consensus::Params { consensus::Params { block: block::Size { max_bytes: 22020096, - max_gas: -1, // Tendetmint-go also has + max_gas: -1, // Tendetmint-go also has time_iota_ms: 1000, // 1s }, evidence: evidence::Params { From 9b59b295ab77fab7b3dc2df7292f06ccfc688f29 Mon Sep 17 00:00:00 2001 From: cezarad Date: Tue, 13 Jul 2021 15:30:18 +0200 Subject: [PATCH 26/32] moved predicates into ics07 header.rs --- modules/src/ics02_client/error.rs | 14 -- .../src/ics02_client/handler/update_client.rs | 2 +- modules/src/ics07_tendermint/client_def.rs | 20 +- modules/src/ics07_tendermint/error.rs | 15 ++ modules/src/ics07_tendermint/header.rs | 190 ++++++++++++++++-- modules/src/ics07_tendermint/mod.rs | 2 +- 6 files changed, 200 insertions(+), 43 deletions(-) diff --git a/modules/src/ics02_client/error.rs b/modules/src/ics02_client/error.rs index d00ad7caed..d6779d6812 100644 --- a/modules/src/ics02_client/error.rs +++ b/modules/src/ics02_client/error.rs @@ -135,24 +135,10 @@ pub enum Kind { #[error("header not withing trusting period: expires_at={0} now={1}")] HeaderNotWithinTrustPeriod(Timestamp, Timestamp), - #[error( - "Header timestamp {0} is outside the trusting period w.r.t. consenus state timestamp{1}" - )] - HeaderTimestampOutsideTrustingTime(String, String), - #[error("Header revision {0} and client state revision {1} should coincide")] MismatchedRevisions(u64, u64), - - #[error(" hearder height {0} must be at greater than current client height {1}")] - LowUpdateHeight(Height, Height), - // #[error(" hearder timestamp {0} must be at greater than current client consensus state timestamp {1}")] // LowUpdateTimestamp(Timestamp, Timestamp), - #[error(" hearder timestamp {0} must be at greater than current client consensus state timestamp {1}")] - LowUpdateTimestamp(String, String), - - #[error(" hearder height = {0} is invalid")] - InvalidHeaderHeight(Height), } impl Kind { diff --git a/modules/src/ics02_client/handler/update_client.rs b/modules/src/ics02_client/handler/update_client.rs index 52e9f1b5f3..5fb80d3688 100644 --- a/modules/src/ics02_client/handler/update_client.rs +++ b/modules/src/ics02_client/handler/update_client.rs @@ -386,7 +386,7 @@ mod tests { match result { Update(upd_res) => { assert_eq!(upd_res.client_id, client_id); - assert!(upd_res.client_state.is_frozen()); + assert!(!upd_res.client_state.is_frozen()); assert_eq!(upd_res.client_state.latest_height(), msg.header.height(),) } _ => panic!("update handler result has incorrect type"), diff --git a/modules/src/ics07_tendermint/client_def.rs b/modules/src/ics07_tendermint/client_def.rs index 1aaa15c363..5cea1b502e 100644 --- a/modules/src/ics07_tendermint/client_def.rs +++ b/modules/src/ics07_tendermint/client_def.rs @@ -12,7 +12,7 @@ use crate::ics04_channel::packet::Sequence; use crate::ics07_tendermint::client_state::ClientState; use crate::ics07_tendermint::consensus_state::ConsensusState; use crate::ics07_tendermint::header::Header; -use crate::ics07_tendermint::predicates::Predicates; +use crate::ics07_tendermint::header::{monotonicity_checks, voting_power_in}; use crate::ics23_commitment::commitment::{CommitmentPrefix, CommitmentProofBytes, CommitmentRoot}; use crate::ics24_host::identifier::ConnectionId; @@ -41,9 +41,6 @@ impl ClientDef for TendermintClient { // check if a consensus state is already installed; if so it should // match the untrusted header. - //TODO remove: - // let time = header.signed_header.header.time; - if let Some(cs) = ctx.consensus_state(&client_id, header.height()) { //could the header height be zero ? let consensus_state = downcast!( @@ -51,9 +48,6 @@ impl ClientDef for TendermintClient { ) .ok_or_else(|| Kind::ClientArgsTypeMismatch(ClientType::Tendermint))?; - // //TODO remove: - // header.signed_header.header.time = consensus_state.timestamp; - if consensus_state != ConsensusState::from(header.clone()) { //freeze the client and return the installed consensus state return Ok(( @@ -64,8 +58,6 @@ impl ClientDef for TendermintClient { return Ok((client_state, consensus_state)); } }; - // //TODO remove: - // header.signed_header.header.time = time; let latest_consensus_state = match ctx.consensus_state(&client_id, client_state.latest_height) { @@ -83,9 +75,7 @@ impl ClientDef for TendermintClient { } }; - let pred = Predicates::default(); - - pred.monotonicity_checks(latest_consensus_state, header.clone(), client_state.clone())?; + monotonicity_checks(latest_consensus_state, header.clone(), client_state.clone())?; // check that the versions of the client state and the header match if client_state.latest_height.revision_number != header.height().revision_number { @@ -121,7 +111,7 @@ impl ClientDef for TendermintClient { // check that the validators that sign the commit of the untrusted header // have 2/3 of the voting power of the current validator set. - if let Err(e) = pred.voting_power_in( + if let Err(e) = voting_power_in( &header.signed_header, &header.validator_set, TrustThresholdFraction::TWO_THIRDS, @@ -133,7 +123,7 @@ impl ClientDef for TendermintClient { //check that a subset of the trusted validator set, having 1/3 of the voting power //signes the commit of the untrusted header - if let Err(e) = pred.voting_power_in( + if let Err(e) = voting_power_in( &header.signed_header, &header.trusted_validator_set, TrustThresholdFraction::default(), @@ -143,7 +133,7 @@ impl ClientDef for TendermintClient { // check that the validators that sign the commit of the untrusted header // have 2/3 of the voting power of the current validator set. - if let Err(e) = pred.voting_power_in( + if let Err(e) = voting_power_in( &header.signed_header, &header.validator_set, TrustThresholdFraction::TWO_THIRDS, diff --git a/modules/src/ics07_tendermint/error.rs b/modules/src/ics07_tendermint/error.rs index c978b93876..4beedf5000 100644 --- a/modules/src/ics07_tendermint/error.rs +++ b/modules/src/ics07_tendermint/error.rs @@ -1,3 +1,4 @@ +use crate::Height; use anomaly::{BoxError, Context}; use thiserror::Error; @@ -40,6 +41,20 @@ pub enum Kind { #[error("invalid raw misbehaviour")] InvalidRawMisbehaviour, + + #[error(" hearder timestamp {0} must be at greater than current client consensus state timestamp {1}")] + LowUpdateTimestamp(String, String), + + #[error( + "Header timestamp {0} is outside the trusting period w.r.t. consenus state timestamp{1}" + )] + HeaderTimestampOutsideTrustingTime(String, String), + + #[error(" hearder height = {0} is invalid")] + InvalidHeaderHeight(Height), + + #[error(" hearder height {0} must be at greater than current client height {1}")] + LowUpdateHeight(Height, Height), } impl Kind { diff --git a/modules/src/ics07_tendermint/header.rs b/modules/src/ics07_tendermint/header.rs index 9f041fb0b6..87ba3204bf 100644 --- a/modules/src/ics07_tendermint/header.rs +++ b/modules/src/ics07_tendermint/header.rs @@ -6,14 +6,24 @@ use tendermint::validator::Set as ValidatorSet; use tendermint::Time; use tendermint_proto::Protobuf; +use crate::ics07_tendermint::error::VerificationError; +use tendermint::block::{Commit, CommitSig}; +use tendermint::trust_threshold::TrustThreshold; +use tendermint::trust_threshold::TrustThresholdFraction; +use tendermint::vote::{SignedVote, ValidatorIndex, Vote}; + use ibc_proto::ibc::lightclients::tendermint::v1::Header as RawHeader; use crate::ics02_client::client_type::ClientType; use crate::ics02_client::header::AnyHeader; +use crate::ics07_tendermint::client_state::ClientState; +use crate::ics07_tendermint::consensus_state::ConsensusState; use crate::ics07_tendermint::error::{Error, Kind}; use crate::ics24_host::identifier::ChainId; use crate::Height; use std::cmp::Ordering; +use std::collections::HashSet; +use std::ops::Sub; /// Tendermint consensus header #[derive(Clone, PartialEq, Deserialize, Serialize)] // TODO: Add Eq bound once present in tendermint-rs @@ -65,21 +75,177 @@ pub fn headers_compatible(header: &SignedHeader, other: &SignedHeader) -> bool { header.header.time < other.header.time } } +} + +pub fn monotonicity_checks( + latest_consensus_state: ConsensusState, + header: Header, + client_state: ClientState, +) -> Result<(), Box> { + if client_state.latest_height() >= header.height() { + return Err(Kind::LowUpdateHeight(header.height(), client_state.latest_height).into()); + } + + if header.height().is_zero() { + return Err(Kind::InvalidHeaderHeight(header.height()).into()); + } + + //check header timestamp is increasing + if latest_consensus_state.timestamp >= header.signed_header.header().time { + return Err(Kind::HeaderTimestampOutsideTrustingTime( + header.signed_header.header().time.as_rfc3339(), + latest_consensus_state.timestamp.as_rfc3339(), + ) + .into()); + }; + + // check that the header is not outside the trusting period + if header + .signed_header + .header() + .time + .sub(client_state.trusting_period) + >= latest_consensus_state.timestamp + { + return Err(Kind::LowUpdateTimestamp( + header.signed_header.header().time.as_rfc3339(), + latest_consensus_state.timestamp.as_rfc3339(), + ) + .into()); + }; + + // check monotonicity of header height vs trusted height. + // unclear needed + if header.trusted_height >= header.height() { + return Err(format!( + "non monotonic height update w.r.t trusted header {}, {:?}", + header.trusted_height, + header.height() + ) + .into()); + }; + + Ok(()) +} + +/// Compute the voting power in a header and its commit against a validator set. +/// +/// The `trust_threshold` is currently not used, but might be in the future +/// for optimization purposes. +pub fn voting_power_in( + signed_header: &SignedHeader, + validator_set: &ValidatorSet, + trust_threshold: TrustThresholdFraction, +) -> Result<(), Box> { + let signatures = &signed_header.commit.signatures; + + let mut tallied_voting_power = 0_u64; + let mut seen_validators = HashSet::new(); + + // Get non-absent votes from the signatures + let non_absent_votes = signatures.iter().enumerate().flat_map(|(idx, signature)| { + non_absent_vote( + signature, + ValidatorIndex::try_from(idx).unwrap(), + &signed_header.commit, + ) + .map(|vote| (signature, vote)) + }); + + let total_voting_power = total_power_of(validator_set); + + for (signature, vote) in non_absent_votes { + // Ensure we only count a validator's power once + if seen_validators.contains(&vote.validator_address) { + return Err(VerificationError::DuplicateValidator(vote.validator_address).into()); + } else { + seen_validators.insert(vote.validator_address); + } + + let validator = match validator_set.validator(vote.validator_address) { + Some(validator) => validator, + None => continue, // Cannot find matching validator, so we skip the vote + }; + + let signed_vote = SignedVote::new( + vote.clone(), + signed_header.header.chain_id.clone(), + vote.validator_address, + vote.signature, + ); + + let sign_bytes = signed_vote.sign_bytes(); + // Check vote is valid + if validator + .verify_signature(&sign_bytes, signed_vote.signature()) + .is_err() + { + //continue; + return Err((VerificationError::InvalidSignature { + signature: signed_vote.signature().to_bytes(), + validator: Box::new(validator), + sign_bytes, + }) + .into()); + } + + // If the vote is neither absent nor nil, tally its power + if signature.is_commit() { + tallied_voting_power += validator.power(); + if trust_threshold.is_enough_power(tallied_voting_power, total_voting_power) { + return Ok(()); + } + } else { + // It's OK. We include stray signatures (~votes for nil) + // to measure validator availability. + } + } + + Err(VerificationError::InsufficientOverlap(tallied_voting_power, total_voting_power).into()) +} - // pub fn header_equality(&self, other_header: &Header) -> bool{ - // let other_height = other_header.signed_header.header.height; - // let self_height = self.signed_header.header.height; - // //TODO we need signed header eq - // if self.signed_header.header != other_header.signed_header.header - // return false; - // } +/// Compute the total voting power in a validator set +fn total_power_of(validator_set: &ValidatorSet) -> u64 { + validator_set + .validators() + .iter() + .fold(0u64, |total, val_info| total + val_info.power.value()) +} - // if self.signed_header.commit != other_header.signed_header.commit - // return false; - // } - // if self.validator_set != other_header.validator_set +fn non_absent_vote( + commit_sig: &CommitSig, + validator_index: ValidatorIndex, + commit: &Commit, +) -> Option { + let (validator_address, timestamp, signature, block_id) = match commit_sig { + CommitSig::BlockIdFlagAbsent { .. } => return None, + CommitSig::BlockIdFlagCommit { + validator_address, + timestamp, + signature, + } => ( + *validator_address, + *timestamp, + signature, + Some(commit.block_id), + ), + CommitSig::BlockIdFlagNil { + validator_address, + timestamp, + signature, + } => (*validator_address, *timestamp, signature, None), + }; - // } + Some(Vote { + vote_type: tendermint::vote::Type::Precommit, + height: commit.height, + round: commit.round, + block_id, + timestamp: Some(timestamp), + validator_address, + validator_index, + signature: *signature, + }) } impl crate::ics02_client::header::Header for Header { diff --git a/modules/src/ics07_tendermint/mod.rs b/modules/src/ics07_tendermint/mod.rs index 46d08727fb..4b981d7450 100644 --- a/modules/src/ics07_tendermint/mod.rs +++ b/modules/src/ics07_tendermint/mod.rs @@ -6,4 +6,4 @@ pub mod consensus_state; pub mod error; pub mod header; pub mod misbehaviour; -pub mod predicates; +//pub mod predicates; From 0c797c8af36b764e8cdb5305b0e46178877dfdb4 Mon Sep 17 00:00:00 2001 From: Adi Seredinschi Date: Wed, 21 Jul 2021 15:49:32 +0200 Subject: [PATCH 27/32] Adapted to latest TM changes --- Cargo.lock | 5 +++++ .../src/ics02_client/handler/create_client.rs | 5 +---- modules/src/ics07_tendermint/client_state.rs | 20 ++++++------------- modules/src/ics07_tendermint/error.rs | 3 +++ modules/src/mock/context.rs | 4 ++-- relayer-cli/src/config.rs | 6 +++--- relayer/src/supervisor/client_state_filter.rs | 2 +- 7 files changed, 21 insertions(+), 24 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0418385071..a184322919 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2954,6 +2954,7 @@ dependencies = [ [[package]] name = "tendermint" version = "0.20.0" +source = "git+https://github.com/informalsystems/tendermint-rs?branch=master#f46cf0f084f406cabca675dbaad1e3032f794621" dependencies = [ "anomaly", "async-trait", @@ -2984,6 +2985,7 @@ dependencies = [ [[package]] name = "tendermint-light-client" version = "0.20.0" +source = "git+https://github.com/informalsystems/tendermint-rs?branch=master#f46cf0f084f406cabca675dbaad1e3032f794621" dependencies = [ "anomaly", "contracts", @@ -3004,6 +3006,7 @@ dependencies = [ [[package]] name = "tendermint-proto" version = "0.20.0" +source = "git+https://github.com/informalsystems/tendermint-rs?branch=master#f46cf0f084f406cabca675dbaad1e3032f794621" dependencies = [ "anomaly", "bytes", @@ -3021,6 +3024,7 @@ dependencies = [ [[package]] name = "tendermint-rpc" version = "0.20.0" +source = "git+https://github.com/informalsystems/tendermint-rs?branch=master#f46cf0f084f406cabca675dbaad1e3032f794621" dependencies = [ "async-trait", "async-tungstenite", @@ -3050,6 +3054,7 @@ dependencies = [ [[package]] name = "tendermint-testgen" version = "0.20.0" +source = "git+https://github.com/informalsystems/tendermint-rs?branch=master#f46cf0f084f406cabca675dbaad1e3032f794621" dependencies = [ "ed25519-dalek", "gumdrop 0.8.0", diff --git a/modules/src/ics02_client/handler/create_client.rs b/modules/src/ics02_client/handler/create_client.rs index 3b2791aa69..5d2cd2fea4 100644 --- a/modules/src/ics02_client/handler/create_client.rs +++ b/modules/src/ics02_client/handler/create_client.rs @@ -224,10 +224,7 @@ mod tests { let tm_client_state = AnyClientState::Tendermint(ClientState { chain_id: tm_header.chain_id.clone().into(), - trust_level: TrustThreshold { - numerator: 1, - denominator: 3, - }, + trust_level: TrustThreshold::ONE_THIRD, trusting_period: Duration::from_secs(64000), unbonding_period: Duration::from_secs(128000), max_clock_drift: Duration::from_millis(3000), diff --git a/modules/src/ics07_tendermint/client_state.rs b/modules/src/ics07_tendermint/client_state.rs index 92a2326b77..c2e150f921 100644 --- a/modules/src/ics07_tendermint/client_state.rs +++ b/modules/src/ics07_tendermint/client_state.rs @@ -122,10 +122,7 @@ impl ClientState { /// Resets all fields except the blockchain-specific ones. pub fn zero_custom_fields(mut client_state: Self) -> Self { client_state.trusting_period = ZERO_DURATION; - client_state.trust_level = TrustThresholdFraction { - numerator: 0, - denominator: 0, - }; + client_state.trust_level = TrustThresholdFraction::default(); client_state.allow_update.after_expiry = false; client_state.allow_update.after_misbehaviour = false; client_state.frozen_height = Height::zero(); @@ -180,10 +177,8 @@ impl TryFrom for ClientState { Ok(Self { chain_id: ChainId::from_str(raw.chain_id.as_str()) .map_err(|_| Kind::InvalidRawClientState.context("Invalid chain identifier"))?, - trust_level: TrustThreshold { - numerator: trust_level.numerator, - denominator: trust_level.denominator, - }, + trust_level: TrustThreshold::new(trust_level.numerator, trust_level.denominator) + .map_err(|e| Kind::InvalidTrustThreshold.context(e))?, trusting_period: raw .trusting_period .ok_or_else(|| Kind::InvalidRawClientState.context("missing trusting period"))? @@ -223,8 +218,8 @@ impl From for RawClientState { RawClientState { chain_id: value.chain_id.to_string(), trust_level: Some(Fraction { - numerator: value.trust_level.numerator, - denominator: value.trust_level.denominator, + numerator: value.trust_level.numerator(), + denominator: value.trust_level.denominator(), }), trusting_period: Some(value.trusting_period.into()), unbonding_period: Some(value.unbonding_period.into()), @@ -286,10 +281,7 @@ mod tests { // Define a "default" set of parameters to reuse throughout these tests. let default_params: ClientStateParams = ClientStateParams { id: ChainId::default(), - trust_level: TrustThreshold { - numerator: 1, - denominator: 3, - }, + trust_level: TrustThreshold::ONE_THIRD, trusting_period: Duration::new(64000, 0), unbonding_period: Duration::new(128000, 0), max_clock_drift: Duration::new(3, 0), diff --git a/modules/src/ics07_tendermint/error.rs b/modules/src/ics07_tendermint/error.rs index 4beedf5000..12b8678f5b 100644 --- a/modules/src/ics07_tendermint/error.rs +++ b/modules/src/ics07_tendermint/error.rs @@ -12,6 +12,9 @@ pub enum Kind { #[error("invalid trusting period")] InvalidTrustingPeriod, + #[error("invalid client state trust threshold ")] + InvalidTrustThreshold, + #[error("invalid unbonding period")] InvalidUnboundingPeriod, diff --git a/modules/src/mock/context.rs b/modules/src/mock/context.rs index 3d34dc16c2..9e78263ffb 100644 --- a/modules/src/mock/context.rs +++ b/modules/src/mock/context.rs @@ -257,7 +257,7 @@ impl MockContext { // If it's a mock client, create the corresponding mock states. ClientType::Mock => ( Some(MockClientState(MockHeader::new(client_state_height)).into()), - MockConsensusState(MockHeader::new(cs_height)).into(), + MockConsensusState::new(MockHeader::new(cs_height)).into(), ), // If it's a Tendermint client, we need TM states. ClientType::Tendermint => { @@ -277,7 +277,7 @@ impl MockContext { let prev_consensus_state = match client_type { // If it's a mock client, create the corresponding mock states. - ClientType::Mock => MockConsensusState(MockHeader::new(prev_cs_height)).into(), + ClientType::Mock => MockConsensusState::new(MockHeader::new(prev_cs_height)).into(), // If it's a Tendermint client, we need TM states. ClientType::Tendermint => { let light_block = HostBlock::generate_tm_block( diff --git a/relayer-cli/src/config.rs b/relayer-cli/src/config.rs index 4a2f3c3231..799ad763bd 100644 --- a/relayer-cli/src/config.rs +++ b/relayer-cli/src/config.rs @@ -64,7 +64,7 @@ pub fn validate_config(config: &Config) -> Result<(), Error> { /// b) greater or equal to 1/3 /// c) strictly less than 1 fn validate_trust_threshold(id: &ChainId, trust_threshold: TrustThreshold) -> Result<(), Error> { - if trust_threshold.denominator == 0 { + if trust_threshold.denominator() == 0 { return Err(Error::InvalidTrustThreshold( trust_threshold, id.clone(), @@ -72,7 +72,7 @@ fn validate_trust_threshold(id: &ChainId, trust_threshold: TrustThreshold) -> Re )); } - if trust_threshold.numerator * 3 < trust_threshold.denominator { + if trust_threshold.numerator() * 3 < trust_threshold.denominator() { return Err(Error::InvalidTrustThreshold( trust_threshold, id.clone(), @@ -80,7 +80,7 @@ fn validate_trust_threshold(id: &ChainId, trust_threshold: TrustThreshold) -> Re )); } - if trust_threshold.numerator >= trust_threshold.denominator { + if trust_threshold.numerator() >= trust_threshold.denominator() { return Err(Error::InvalidTrustThreshold( trust_threshold, id.clone(), diff --git a/relayer/src/supervisor/client_state_filter.rs b/relayer/src/supervisor/client_state_filter.rs index eba34a9fa0..2ef2bb10b7 100644 --- a/relayer/src/supervisor/client_state_filter.rs +++ b/relayer/src/supervisor/client_state_filter.rs @@ -129,7 +129,7 @@ impl FilterPolicy { } let permission = match state.trust_threshold() { - Some(trust) if trust.numerator == 1 && trust.denominator == 3 => Permission::Allow, + Some(trust) if trust.numerator() == 1 && trust.denominator() == 3 => Permission::Allow, Some(_) => { trace!( "[client filter] client {} on chain {} has a trust threshold different than 1/3", From f94b42dfc16d799ab24e257827c698b5c31ff19f Mon Sep 17 00:00:00 2001 From: Adi Seredinschi Date: Wed, 21 Jul 2021 16:00:30 +0200 Subject: [PATCH 28/32] Fixed MockHeader test --- modules/src/ics02_client/handler/update_client.rs | 9 ++++----- modules/src/ics26_routing/handler.rs | 7 ++++--- modules/src/mock/header.rs | 10 +++++++--- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/modules/src/ics02_client/handler/update_client.rs b/modules/src/ics02_client/handler/update_client.rs index 5fb80d3688..b5e2862479 100644 --- a/modules/src/ics02_client/handler/update_client.rs +++ b/modules/src/ics02_client/handler/update_client.rs @@ -136,7 +136,7 @@ mod tests { let ctx = MockContext::default().with_client(&client_id, Height::new(0, 42)); let msg = MsgUpdateAnyClient { client_id: client_id.clone(), - header: MockHeader::new_time(Height::new(0, 46), timestamp).into(), + header: MockHeader::new(Height::new(0, 46)).with_timestamp(timestamp).into(), signer, }; @@ -160,10 +160,9 @@ mod tests { assert_eq!(upd_res.client_id, client_id); assert_eq!( upd_res.client_state, - AnyClientState::Mock(MockClientState(MockHeader::new_time( - msg.header.height(), - timestamp - ))) + AnyClientState::Mock(MockClientState(MockHeader::new( + msg.header.height() + ).with_timestamp(timestamp))) ) } _ => panic!("update handler result has incorrect type"), diff --git a/modules/src/ics26_routing/handler.rs b/modules/src/ics26_routing/handler.rs index d470f83e63..7edefe0688 100644 --- a/modules/src/ics26_routing/handler.rs +++ b/modules/src/ics26_routing/handler.rs @@ -174,6 +174,7 @@ mod tests { use crate::mock::header::MockHeader; use crate::test_utils::get_dummy_account_id; use crate::Height; + use crate::timestamp::Timestamp; #[test] /// These tests exercise two main paths: (1) the ability of the ICS26 routing module to dispatch @@ -302,7 +303,7 @@ mod tests { name: "Client update successful".to_string(), msg: Ics26Envelope::Ics2Msg(ClientMsg::UpdateClient(MsgUpdateAnyClient { client_id: client_id.clone(), - header: MockHeader::new(update_client_height).into(), + header: MockHeader::new(update_client_height).with_timestamp(Timestamp::now()).into(), signer: default_signer.clone(), })), want_pass: true, @@ -377,10 +378,10 @@ mod tests { // The client update is required in this test, because the proof associated with // msg_recv_packet has the same height as the packet TO height (see get_dummy_raw_msg_recv_packet) Test { - name: "Client update successful".to_string(), + name: "Client update successful #2".to_string(), msg: Ics26Envelope::Ics2Msg(ClientMsg::UpdateClient(MsgUpdateAnyClient { client_id: client_id.clone(), - header: MockHeader::new(update_client_height_after_send).into(), + header: MockHeader::new(update_client_height_after_send).with_timestamp(Timestamp::now()).into(), signer: default_signer.clone(), })), want_pass: true, diff --git a/modules/src/mock/header.rs b/modules/src/mock/header.rs index cf7c5b02db..138d7b08d8 100644 --- a/modules/src/mock/header.rs +++ b/modules/src/mock/header.rs @@ -55,11 +55,15 @@ impl MockHeader { pub fn new(height: Height) -> Self { Self { height, - timestamp: Timestamp::now(), //Default::default(), + timestamp: Default::default(), } } - pub fn new_time(height: Height, timestamp: Timestamp) -> Self { - Self { height, timestamp } + + pub fn with_timestamp(self, timestamp: Timestamp) -> Self { + Self { + timestamp, + ..self + } } } From de1af84dcce84248f55f01983589948ce1aa8f7e Mon Sep 17 00:00:00 2001 From: Adi Seredinschi Date: Wed, 21 Jul 2021 16:01:45 +0200 Subject: [PATCH 29/32] Fmt & clippy --- modules/src/ics02_client/handler/update_client.rs | 10 ++++++---- modules/src/ics26_routing/handler.rs | 10 +++++++--- modules/src/mock/header.rs | 5 +---- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/modules/src/ics02_client/handler/update_client.rs b/modules/src/ics02_client/handler/update_client.rs index b5e2862479..d0e424839e 100644 --- a/modules/src/ics02_client/handler/update_client.rs +++ b/modules/src/ics02_client/handler/update_client.rs @@ -136,7 +136,9 @@ mod tests { let ctx = MockContext::default().with_client(&client_id, Height::new(0, 42)); let msg = MsgUpdateAnyClient { client_id: client_id.clone(), - header: MockHeader::new(Height::new(0, 46)).with_timestamp(timestamp).into(), + header: MockHeader::new(Height::new(0, 46)) + .with_timestamp(timestamp) + .into(), signer, }; @@ -160,9 +162,9 @@ mod tests { assert_eq!(upd_res.client_id, client_id); assert_eq!( upd_res.client_state, - AnyClientState::Mock(MockClientState(MockHeader::new( - msg.header.height() - ).with_timestamp(timestamp))) + AnyClientState::Mock(MockClientState( + MockHeader::new(msg.header.height()).with_timestamp(timestamp) + )) ) } _ => panic!("update handler result has incorrect type"), diff --git a/modules/src/ics26_routing/handler.rs b/modules/src/ics26_routing/handler.rs index 7edefe0688..3c481b538b 100644 --- a/modules/src/ics26_routing/handler.rs +++ b/modules/src/ics26_routing/handler.rs @@ -173,8 +173,8 @@ mod tests { use crate::mock::context::MockContext; use crate::mock::header::MockHeader; use crate::test_utils::get_dummy_account_id; - use crate::Height; use crate::timestamp::Timestamp; + use crate::Height; #[test] /// These tests exercise two main paths: (1) the ability of the ICS26 routing module to dispatch @@ -303,7 +303,9 @@ mod tests { name: "Client update successful".to_string(), msg: Ics26Envelope::Ics2Msg(ClientMsg::UpdateClient(MsgUpdateAnyClient { client_id: client_id.clone(), - header: MockHeader::new(update_client_height).with_timestamp(Timestamp::now()).into(), + header: MockHeader::new(update_client_height) + .with_timestamp(Timestamp::now()) + .into(), signer: default_signer.clone(), })), want_pass: true, @@ -381,7 +383,9 @@ mod tests { name: "Client update successful #2".to_string(), msg: Ics26Envelope::Ics2Msg(ClientMsg::UpdateClient(MsgUpdateAnyClient { client_id: client_id.clone(), - header: MockHeader::new(update_client_height_after_send).with_timestamp(Timestamp::now()).into(), + header: MockHeader::new(update_client_height_after_send) + .with_timestamp(Timestamp::now()) + .into(), signer: default_signer.clone(), })), want_pass: true, diff --git a/modules/src/mock/header.rs b/modules/src/mock/header.rs index 138d7b08d8..9d0e034404 100644 --- a/modules/src/mock/header.rs +++ b/modules/src/mock/header.rs @@ -60,10 +60,7 @@ impl MockHeader { } pub fn with_timestamp(self, timestamp: Timestamp) -> Self { - Self { - timestamp, - ..self - } + Self { timestamp, ..self } } } From d48b18559918a97369bf1cdef9a38dd97291e1c1 Mon Sep 17 00:00:00 2001 From: Adi Seredinschi Date: Wed, 21 Jul 2021 16:02:29 +0200 Subject: [PATCH 30/32] Removed irrelevant file --- modules/mc.log | 407 ------------------------------------------------- 1 file changed, 407 deletions(-) delete mode 100644 modules/mc.log diff --git a/modules/mc.log b/modules/mc.log deleted file mode 100644 index a4e5349fb8..0000000000 --- a/modules/mc.log +++ /dev/null @@ -1,407 +0,0 @@ -@!@!@STARTMSG 2262:0 @!@!@ -TLC2 Version 2.15 of Day Month 20?? (rev: 920e6fa) -@!@!@ENDMSG 2262 @!@!@ -@!@!@STARTMSG 2401:3 @!@!@ -Please run the Java VM, which executes TLC with a throughput optimized garbage collector, by passing the "-XX:+UseParallelGC" property. -@!@!@ENDMSG 2401 @!@!@ -@!@!@STARTMSG 2187:0 @!@!@ -Running breadth-first search Model-Checking with fp 94 and seed 965814849019522492 with 8 workers on 8 cores with 4096MB heap and 64MB offheap memory [pid: 44931] (Mac OS X 10.16 x86_64, Oracle Corporation 10 x86_64, MSBDiskFPSet, DiskStateQueue). -@!@!@ENDMSG 2187 @!@!@ -@!@!@STARTMSG 2220:0 @!@!@ -Starting SANY... -@!@!@ENDMSG 2220 @!@!@ -Parsing file /Users/idragoi/Documents/GitHub/ibc-rs/modules/tests/support/model_based/IBCTests_ICS03ConnectionOpenConfirmOKTest.tla -Parsing file /Users/idragoi/Documents/GitHub/ibc-rs/modules/tests/support/model_based/IBCTests.tla -Parsing file /Users/idragoi/Documents/GitHub/ibc-rs/modules/tests/support/model_based/IBC.tla -Parsing file /Users/idragoi/Documents/GitHub/ibc-rs/modules/tests/support/model_based/ICS02.tla -Parsing file /Users/idragoi/Documents/GitHub/ibc-rs/modules/tests/support/model_based/ICS03.tla -Parsing file /Users/idragoi/Documents/GitHub/ibc-rs/modules/tests/support/model_based/IBCDefinitions.tla -Parsing file /private/var/folders/j1/w2g38g0s1d10s9kpwcn6fywm00lx47/T/Integers.tla (jar:file:/Users/idragoi/Documents/GitHub/ibc-rs/modules/.modelator/tla2tools-v1.8.0.jar!/tla2sany/StandardModules/Integers.tla) -Parsing file /private/var/folders/j1/w2g38g0s1d10s9kpwcn6fywm00lx47/T/FiniteSets.tla (jar:file:/Users/idragoi/Documents/GitHub/ibc-rs/modules/.modelator/tla2tools-v1.8.0.jar!/tla2sany/StandardModules/FiniteSets.tla) -Parsing file /private/var/folders/j1/w2g38g0s1d10s9kpwcn6fywm00lx47/T/TLC.tla (jar:file:/Users/idragoi/Documents/GitHub/ibc-rs/modules/.modelator/tla2tools-v1.8.0.jar!/tla2sany/StandardModules/TLC.tla) -Parsing file /private/var/folders/j1/w2g38g0s1d10s9kpwcn6fywm00lx47/T/Naturals.tla (jar:file:/Users/idragoi/Documents/GitHub/ibc-rs/modules/.modelator/tla2tools-v1.8.0.jar!/tla2sany/StandardModules/Naturals.tla) -Parsing file /private/var/folders/j1/w2g38g0s1d10s9kpwcn6fywm00lx47/T/Sequences.tla (jar:file:/Users/idragoi/Documents/GitHub/ibc-rs/modules/.modelator/tla2tools-v1.8.0.jar!/tla2sany/StandardModules/Sequences.tla) -Semantic processing of module Naturals -Semantic processing of module Integers -Semantic processing of module Sequences -Semantic processing of module FiniteSets -Semantic processing of module TLC -Semantic processing of module IBCDefinitions -Semantic processing of module ICS02 -Semantic processing of module ICS03 -Semantic processing of module IBC -Semantic processing of module IBCTests -Semantic processing of module IBCTests_ICS03ConnectionOpenConfirmOKTest -@!@!@STARTMSG 2219:0 @!@!@ -SANY finished. -@!@!@ENDMSG 2219 @!@!@ -@!@!@STARTMSG 2185:0 @!@!@ -Starting... (2021-06-20 10:17:41) -@!@!@ENDMSG 2185 @!@!@ -@!@!@STARTMSG 2189:0 @!@!@ -Computing initial states... -@!@!@ENDMSG 2189 @!@!@ -@!@!@STARTMSG 2190:0 @!@!@ -Finished computing initial states: 1 distinct state generated at 2021-06-20 10:17:42. -@!@!@ENDMSG 2190 @!@!@ -@!@!@STARTMSG 2200:0 @!@!@ -Progress(6) at 2021-06-20 10:17:45: 376,807 states generated (376,807 s/min), 11,083 distinct states found (11,083 ds/min), 6,513 states left on queue. -@!@!@ENDMSG 2200 @!@!@ -@!@!@STARTMSG 2110:1 @!@!@ -Invariant ICS03ConnectionOpenConfirmOKTestNeg is violated. -@!@!@ENDMSG 2110 @!@!@ -@!@!@STARTMSG 2121:1 @!@!@ -The behavior up to this point is: -@!@!@ENDMSG 2121 @!@!@ -@!@!@STARTMSG 2217:4 @!@!@ -1: -/\ actionOutcome = "None" -/\ chains = [ chainA |-> - [ height |-> 1, - clients |-> (0 :> [heights |-> {}]), - clientIdCounter |-> 0, - connections |-> - ( 0 :> - [ chainId |-> "-1", - clientId |-> -1, - counterpartyChainId |-> "-1", - counterpartyClientId |-> -1, - counterpartyConnectionId |-> -1, - connectionId |-> -1, - state |-> "Uninitialized" ] ), - connectionIdCounter |-> 0, - connectionProofs |-> {} ], - chainB |-> - [ height |-> 1, - clients |-> (0 :> [heights |-> {}]), - clientIdCounter |-> 0, - connections |-> - ( 0 :> - [ chainId |-> "-1", - clientId |-> -1, - counterpartyChainId |-> "-1", - counterpartyClientId |-> -1, - counterpartyConnectionId |-> -1, - connectionId |-> -1, - state |-> "Uninitialized" ] ), - connectionIdCounter |-> 0, - connectionProofs |-> {} ] ] -/\ action = [type |-> "None"] - -@!@!@ENDMSG 2217 @!@!@ -@!@!@STARTMSG 2217:4 @!@!@ -2: -/\ actionOutcome = "Ics02CreateOk" -/\ chains = [ chainA |-> - [ height |-> 2, - clients |-> (0 :> [heights |-> {2}]), - clientIdCounter |-> 1, - connections |-> - ( 0 :> - [ chainId |-> "-1", - clientId |-> -1, - counterpartyChainId |-> "-1", - counterpartyClientId |-> -1, - counterpartyConnectionId |-> -1, - connectionId |-> -1, - state |-> "Uninitialized" ] ), - connectionIdCounter |-> 0, - connectionProofs |-> {} ], - chainB |-> - [ height |-> 1, - clients |-> (0 :> [heights |-> {}]), - clientIdCounter |-> 0, - connections |-> - ( 0 :> - [ chainId |-> "-1", - clientId |-> -1, - counterpartyChainId |-> "-1", - counterpartyClientId |-> -1, - counterpartyConnectionId |-> -1, - connectionId |-> -1, - state |-> "Uninitialized" ] ), - connectionIdCounter |-> 0, - connectionProofs |-> {} ] ] -/\ action = [ type |-> "Ics02CreateClient", - chainId |-> "chainA", - clientState |-> 2, - consensusState |-> 2 ] - -@!@!@ENDMSG 2217 @!@!@ -@!@!@STARTMSG 2217:4 @!@!@ -3: -/\ actionOutcome = "Ics03ConnectionOpenInitOk" -/\ chains = [ chainA |-> - [ height |-> 3, - clients |-> (0 :> [heights |-> {2}]), - clientIdCounter |-> 1, - connections |-> - ( 0 :> - [ chainId |-> "chainA", - clientId |-> 0, - counterpartyChainId |-> "chainB", - counterpartyClientId |-> 0, - counterpartyConnectionId |-> -1, - connectionId |-> 0, - state |-> "Init" ] ), - connectionIdCounter |-> 1, - connectionProofs |-> {} ], - chainB |-> - [ height |-> 1, - clients |-> (0 :> [heights |-> {}]), - clientIdCounter |-> 0, - connections |-> - ( 0 :> - [ chainId |-> "-1", - clientId |-> -1, - counterpartyChainId |-> "-1", - counterpartyClientId |-> -1, - counterpartyConnectionId |-> -1, - connectionId |-> -1, - state |-> "Uninitialized" ] ), - connectionIdCounter |-> 0, - connectionProofs |-> - { [ type |-> "Ics03ConnectionOpenInit", - chainId |-> "chainA", - clientId |-> 0, - counterpartyChainId |-> "chainB", - counterpartyClientId |-> 0 ] } ] ] -/\ action = [ type |-> "Ics03ConnectionOpenInit", - chainId |-> "chainA", - clientId |-> 0, - counterpartyChainId |-> "chainB", - counterpartyClientId |-> 0 ] - -@!@!@ENDMSG 2217 @!@!@ -@!@!@STARTMSG 2217:4 @!@!@ -4: -/\ actionOutcome = "Ics02CreateOk" -/\ chains = [ chainA |-> - [ height |-> 3, - clients |-> (0 :> [heights |-> {2}]), - clientIdCounter |-> 1, - connections |-> - ( 0 :> - [ chainId |-> "chainA", - clientId |-> 0, - counterpartyChainId |-> "chainB", - counterpartyClientId |-> 0, - counterpartyConnectionId |-> -1, - connectionId |-> 0, - state |-> "Init" ] ), - connectionIdCounter |-> 1, - connectionProofs |-> {} ], - chainB |-> - [ height |-> 2, - clients |-> (0 :> [heights |-> {1}]), - clientIdCounter |-> 1, - connections |-> - ( 0 :> - [ chainId |-> "-1", - clientId |-> -1, - counterpartyChainId |-> "-1", - counterpartyClientId |-> -1, - counterpartyConnectionId |-> -1, - connectionId |-> -1, - state |-> "Uninitialized" ] ), - connectionIdCounter |-> 0, - connectionProofs |-> - { [ type |-> "Ics03ConnectionOpenInit", - chainId |-> "chainA", - clientId |-> 0, - counterpartyChainId |-> "chainB", - counterpartyClientId |-> 0 ] } ] ] -/\ action = [ type |-> "Ics02CreateClient", - chainId |-> "chainB", - clientState |-> 1, - consensusState |-> 1 ] - -@!@!@ENDMSG 2217 @!@!@ -@!@!@STARTMSG 2217:4 @!@!@ -5: -/\ actionOutcome = "Ics03ConnectionOpenTryOk" -/\ chains = [ chainA |-> - [ height |-> 3, - clients |-> (0 :> [heights |-> {2}]), - clientIdCounter |-> 1, - connections |-> - ( 0 :> - [ chainId |-> "chainA", - clientId |-> 0, - counterpartyChainId |-> "chainB", - counterpartyClientId |-> 0, - counterpartyConnectionId |-> -1, - connectionId |-> 0, - state |-> "Init" ] ), - connectionIdCounter |-> 1, - connectionProofs |-> - { [ type |-> "Ics03ConnectionOpenTry", - chainId |-> "chainB", - clientState |-> 1, - clientId |-> 0, - counterpartyChainId |-> "chainA", - counterpartyClientId |-> 0, - previousConnectionId |-> -1, - counterpartyConnectionId |-> 0 ] } ], - chainB |-> - [ height |-> 3, - clients |-> (0 :> [heights |-> {1}]), - clientIdCounter |-> 1, - connections |-> - ( 0 :> - [ chainId |-> "chainB", - clientId |-> 0, - counterpartyChainId |-> "chainA", - counterpartyClientId |-> 0, - counterpartyConnectionId |-> 0, - connectionId |-> 0, - state |-> "TryOpen" ] ), - connectionIdCounter |-> 1, - connectionProofs |-> - { [ type |-> "Ics03ConnectionOpenInit", - chainId |-> "chainA", - clientId |-> 0, - counterpartyChainId |-> "chainB", - counterpartyClientId |-> 0 ] } ] ] -/\ action = [ type |-> "Ics03ConnectionOpenTry", - chainId |-> "chainB", - clientState |-> 1, - clientId |-> 0, - counterpartyChainId |-> "chainA", - counterpartyClientId |-> 0, - previousConnectionId |-> -1, - counterpartyConnectionId |-> 0 ] - -@!@!@ENDMSG 2217 @!@!@ -@!@!@STARTMSG 2217:4 @!@!@ -6: -/\ actionOutcome = "Ics03ConnectionOpenAckOk" -/\ chains = [ chainA |-> - [ height |-> 4, - clients |-> (0 :> [heights |-> {2}]), - clientIdCounter |-> 1, - connections |-> - ( 0 :> - [ chainId |-> "chainA", - clientId |-> 0, - counterpartyChainId |-> "chainB", - counterpartyClientId |-> 0, - counterpartyConnectionId |-> -1, - connectionId |-> 0, - state |-> "Open" ] ), - connectionIdCounter |-> 1, - connectionProofs |-> - { [ type |-> "Ics03ConnectionOpenTry", - chainId |-> "chainB", - clientState |-> 1, - clientId |-> 0, - counterpartyChainId |-> "chainA", - counterpartyClientId |-> 0, - previousConnectionId |-> -1, - counterpartyConnectionId |-> 0 ] } ], - chainB |-> - [ height |-> 3, - clients |-> (0 :> [heights |-> {1}]), - clientIdCounter |-> 1, - connections |-> - ( 0 :> - [ chainId |-> "chainB", - clientId |-> 0, - counterpartyChainId |-> "chainA", - counterpartyClientId |-> 0, - counterpartyConnectionId |-> 0, - connectionId |-> 0, - state |-> "TryOpen" ] ), - connectionIdCounter |-> 1, - connectionProofs |-> - { [ type |-> "Ics03ConnectionOpenInit", - chainId |-> "chainA", - clientId |-> 0, - counterpartyChainId |-> "chainB", - counterpartyClientId |-> 0 ], - [ type |-> "Ics03ConnectionOpenAck", - chainId |-> "chainA", - clientState |-> 2, - counterpartyChainId |-> "chainB", - counterpartyConnectionId |-> 0, - connectionId |-> 0 ] } ] ] -/\ action = [ type |-> "Ics03ConnectionOpenAck", - chainId |-> "chainA", - clientState |-> 2, - counterpartyChainId |-> "chainB", - counterpartyConnectionId |-> 0, - connectionId |-> 0 ] - -@!@!@ENDMSG 2217 @!@!@ -@!@!@STARTMSG 2217:4 @!@!@ -7: -/\ actionOutcome = "Ics03ConnectionOpenConfirmOk" -/\ chains = [ chainA |-> - [ height |-> 4, - clients |-> (0 :> [heights |-> {2}]), - clientIdCounter |-> 1, - connections |-> - ( 0 :> - [ chainId |-> "chainA", - clientId |-> 0, - counterpartyChainId |-> "chainB", - counterpartyClientId |-> 0, - counterpartyConnectionId |-> -1, - connectionId |-> 0, - state |-> "Open" ] ), - connectionIdCounter |-> 1, - connectionProofs |-> - { [ type |-> "Ics03ConnectionOpenTry", - chainId |-> "chainB", - clientState |-> 1, - clientId |-> 0, - counterpartyChainId |-> "chainA", - counterpartyClientId |-> 0, - previousConnectionId |-> -1, - counterpartyConnectionId |-> 0 ] } ], - chainB |-> - [ height |-> 4, - clients |-> (0 :> [heights |-> {1}]), - clientIdCounter |-> 1, - connections |-> - ( 0 :> - [ chainId |-> "chainB", - clientId |-> 0, - counterpartyChainId |-> "chainA", - counterpartyClientId |-> 0, - counterpartyConnectionId |-> 0, - connectionId |-> 0, - state |-> "Open" ] ), - connectionIdCounter |-> 1, - connectionProofs |-> - { [ type |-> "Ics03ConnectionOpenInit", - chainId |-> "chainA", - clientId |-> 0, - counterpartyChainId |-> "chainB", - counterpartyClientId |-> 0 ], - [ type |-> "Ics03ConnectionOpenAck", - chainId |-> "chainA", - clientState |-> 2, - counterpartyChainId |-> "chainB", - counterpartyConnectionId |-> 0, - connectionId |-> 0 ] } ] ] -/\ action = [ type |-> "Ics03ConnectionOpenConfirm", - chainId |-> "chainB", - clientState |-> 1, - counterpartyChainId |-> "chainA", - counterpartyConnectionId |-> 0, - connectionId |-> 0 ] - -@!@!@ENDMSG 2217 @!@!@ -@!@!@STARTMSG 2200:0 @!@!@ -Progress(7) at 2021-06-20 10:17:46: 626,675 states generated (8,044,608 s/min), 14,852 distinct states found (190,654 ds/min), 6,934 states left on queue. -@!@!@ENDMSG 2200 @!@!@ -@!@!@STARTMSG 2199:0 @!@!@ -626675 states generated, 14852 distinct states found, 6934 states left on queue. -@!@!@ENDMSG 2199 @!@!@ -@!@!@STARTMSG 2194:0 @!@!@ -The depth of the complete state graph search is 7. -@!@!@ENDMSG 2194 @!@!@ -@!@!@STARTMSG 2186:0 @!@!@ -Finished in 4677ms at (2021-06-20 10:17:46) -@!@!@ENDMSG 2186 @!@!@ From e6ec46f79ca992f15e1ed04799c5ef8d4ab1a3f9 Mon Sep 17 00:00:00 2001 From: Adi Seredinschi Date: Wed, 21 Jul 2021 16:06:33 +0200 Subject: [PATCH 31/32] Bit more cleanup --- .../ics20_fungible_token_transfer/msgs/transfer.rs | 7 ++++--- modules/src/ics02_client/error.rs | 4 +--- modules/src/ics02_client/handler/update_client.rs | 8 ++++---- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/modules/src/application/ics20_fungible_token_transfer/msgs/transfer.rs b/modules/src/application/ics20_fungible_token_transfer/msgs/transfer.rs index 529602152c..c6e2388eb0 100644 --- a/modules/src/application/ics20_fungible_token_transfer/msgs/transfer.rs +++ b/modules/src/application/ics20_fungible_token_transfer/msgs/transfer.rs @@ -101,16 +101,17 @@ impl From for RawMsgTransfer { #[cfg(test)] pub mod test_util { + use std::ops::Add; + use std::time::Duration; + use crate::{ ics24_host::identifier::{ChannelId, PortId}, test_utils::get_dummy_account_id, + timestamp::Timestamp, Height, }; use super::MsgTransfer; - use crate::timestamp::Timestamp; - use std::ops::Add; - use std::time::Duration; // Returns a dummy `RawMsgTransfer`, for testing only! pub fn get_dummy_msg_transfer(height: u64) -> MsgTransfer { diff --git a/modules/src/ics02_client/error.rs b/modules/src/ics02_client/error.rs index d6779d6812..a58f293201 100644 --- a/modules/src/ics02_client/error.rs +++ b/modules/src/ics02_client/error.rs @@ -1,6 +1,7 @@ use std::num::ParseIntError; use anomaly::{BoxError, Context}; +use tendermint::hash::Hash; use thiserror::Error; use crate::ics02_client::client_type::ClientType; @@ -9,7 +10,6 @@ use crate::ics24_host::error::ValidationKind; use crate::ics24_host::identifier::ClientId; use crate::timestamp::Timestamp; use crate::Height; -use tendermint::hash::Hash; pub type Error = anomaly::Error; @@ -137,8 +137,6 @@ pub enum Kind { #[error("Header revision {0} and client state revision {1} should coincide")] MismatchedRevisions(u64, u64), - // #[error(" hearder timestamp {0} must be at greater than current client consensus state timestamp {1}")] - // LowUpdateTimestamp(Timestamp, Timestamp), } impl Kind { diff --git a/modules/src/ics02_client/handler/update_client.rs b/modules/src/ics02_client/handler/update_client.rs index d0e424839e..186548e2b6 100644 --- a/modules/src/ics02_client/handler/update_client.rs +++ b/modules/src/ics02_client/handler/update_client.rs @@ -1,5 +1,7 @@ //! Protocol logic specific to processing ICS2 messages of type `MsgUpdateAnyClient`. +use tracing::info; + use crate::events::IbcEvent; use crate::handler::{HandlerOutput, HandlerResult}; use crate::ics02_client::client_consensus::AnyConsensusState; @@ -13,8 +15,6 @@ use crate::ics02_client::msgs::update_client::MsgUpdateAnyClient; use crate::ics24_host::identifier::ClientId; use crate::timestamp::Timestamp; -use tracing::info; - /// The result following the successful processing of a `MsgUpdateAnyClient` message. Preferably /// this data type should be used with a qualified name `update_client::Result` to avoid ambiguity. #[derive(Clone, Debug, PartialEq, Eq)] @@ -59,7 +59,7 @@ pub fn process( Kind::ConsensusStateNotFound(client_id.clone(), client_state.latest_height()) })?; - info!("latest conseus state {:?}", latest_consensus_state); + info!("latest consensus state {:?}", latest_consensus_state); let duration = Timestamp::now() .duration_since(&latest_consensus_state.timestamp()) @@ -103,6 +103,7 @@ pub fn process( #[cfg(test)] mod tests { use std::str::FromStr; + use test_env_log::test; use crate::events::IbcEvent; @@ -116,7 +117,6 @@ mod tests { use crate::ics02_client::header::{AnyHeader, Header}; use crate::ics02_client::msgs::update_client::MsgUpdateAnyClient; use crate::ics02_client::msgs::ClientMsg; - use crate::ics24_host::identifier::{ChainId, ClientId}; use crate::mock::client_state::MockClientState; use crate::mock::context::MockContext; From 8c190fc7d12b79bd4715fd5bf713c4bb9612f2d8 Mon Sep 17 00:00:00 2001 From: cezarad Date: Fri, 30 Jul 2021 10:45:07 +0200 Subject: [PATCH 32/32] Update Cargo.toml --- Cargo.toml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 6557fa2729..eb389c9585 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,12 +9,13 @@ members = [ ] exclude = [ + "no-std-check", "proto-compiler" ] [patch.crates-io] - tendermint = { git = "https://github.com/informalsystems/tendermint-rs", branch = "master" } - tendermint-rpc = { git = "https://github.com/informalsystems/tendermint-rs", branch = "master" } - tendermint-proto = { git = "https://github.com/informalsystems/tendermint-rs", branch = "master" } - tendermint-light-client = { git = "https://github.com/informalsystems/tendermint-rs", branch = "master" } - tendermint-testgen = { git = "https://github.com/informalsystems/tendermint-rs", branch = "master" } +# tendermint = { git = "https://github.com/informalsystems/tendermint-rs", branch = "master" } +# tendermint-rpc = { git = "https://github.com/informalsystems/tendermint-rs", branch = "master" } +# tendermint-proto = { git = "https://github.com/informalsystems/tendermint-rs", branch = "master" } +# tendermint-light-client = { git = "https://github.com/informalsystems/tendermint-rs", branch = "master" } +# tendermint-testgen = { git = "https://github.com/informalsystems/tendermint-rs", branch = "master" } \ No newline at end of file