From 0e42e0b02f858792ad63ceb560b6c6d492645968 Mon Sep 17 00:00:00 2001 From: Adi Seredinschi Date: Mon, 9 Nov 2020 14:26:13 +0100 Subject: [PATCH] Bringing changes from the older PR #289, first pass. --- modules/Cargo.toml | 11 +++++++ modules/src/ics02_client/client_def.rs | 44 ++++++++++++------------- modules/src/ics02_client/client_type.rs | 6 ++-- modules/src/ics18_relayer/context.rs | 5 +++ modules/src/ics18_relayer/mod.rs | 3 +- modules/src/ics18_relayer/utils.rs | 3 +- modules/src/lib.rs | 6 ++-- modules/src/mock_context.rs | 6 ++++ 8 files changed, 52 insertions(+), 32 deletions(-) diff --git a/modules/Cargo.toml b/modules/Cargo.toml index c0d54f666a..b97a7fe535 100644 --- a/modules/Cargo.toml +++ b/modules/Cargo.toml @@ -14,6 +14,11 @@ description = """ Implementation of the Inter-Blockchain Communication Protocol (IBC). """ +[features] +# This feature grants access to development-time mocking libraries, such as `MockContext` or `MockHeader`. +# Depends on the `testgen` suite for generating Tendermint light blocks. +mocks = [ "tendermint-testgen" ] + [dependencies] # Proto definitions for all IBC-related interfaces, e.g., connections or channels. ibc-proto = { version = "0.4.0", path = "../proto" } @@ -54,6 +59,12 @@ version = "0.17.0-rc1" git = "https://github.com/informalsystems/tendermint-rs" branch = "greg/research-json" +[dependencies.tendermint-testgen] +version = "0.17.0-rc1" +git = "https://github.com/informalsystems/tendermint-rs" +optional = true + [dev-dependencies] tokio = { version = "0.2", features = ["macros"] } subtle-encoding = { version = "0.5" } +tendermint-testgen = { version = "0.17.0-rc1", git = "https://github.com/informalsystems/tendermint-rs" } # Needed for generating (synthetic) light blocks. \ No newline at end of file diff --git a/modules/src/ics02_client/client_def.rs b/modules/src/ics02_client/client_def.rs index 032449e324..3d68b9fb9a 100644 --- a/modules/src/ics02_client/client_def.rs +++ b/modules/src/ics02_client/client_def.rs @@ -18,7 +18,7 @@ use crate::ics23_commitment::commitment::{CommitmentPrefix, CommitmentProof, Com use crate::ics24_host::identifier::{ClientId, ConnectionId}; use crate::Height; -#[cfg(test)] +#[cfg(any(test, feature = "mocks"))] use { crate::mock_client::client_def::MockClient, crate::mock_client::header::MockHeader, @@ -95,7 +95,7 @@ pub trait ClientDef: Clone { pub enum AnyHeader { Tendermint(tendermint::header::Header), - #[cfg(test)] + #[cfg(any(test, feature = "mocks"))] Mock(MockHeader), } @@ -104,7 +104,7 @@ impl Header for AnyHeader { match self { Self::Tendermint(header) => header.client_type(), - #[cfg(test)] + #[cfg(any(test, feature = "mocks"))] Self::Mock(header) => header.client_type(), } } @@ -113,7 +113,7 @@ impl Header for AnyHeader { match self { Self::Tendermint(header) => header.height(), - #[cfg(test)] + #[cfg(any(test, feature = "mocks"))] Self::Mock(header) => header.height(), } } @@ -131,7 +131,7 @@ impl TryFrom for AnyHeader { .map_err(|e| Kind::InvalidRawHeader.context(e))?, )), - #[cfg(test)] + #[cfg(any(test, feature = "mocks"))] MOCK_HEADER_TYPE_URL => Ok(AnyHeader::Mock( MockHeader::decode_vec(&raw.value) .map_err(|e| Kind::InvalidRawHeader.context(e))?, @@ -149,7 +149,7 @@ impl From for Any { type_url: TENDERMINT_HEADER_TYPE_URL.to_string(), value: header.encode_vec().unwrap(), }, - #[cfg(test)] + #[cfg(any(test, feature = "mocks"))] AnyHeader::Mock(header) => Any { type_url: MOCK_HEADER_TYPE_URL.to_string(), value: header.encode_vec().unwrap(), @@ -162,7 +162,7 @@ impl From for Any { pub enum AnyClientState { Tendermint(TendermintClientState), - #[cfg(test)] + #[cfg(any(test, feature = "mocks"))] Mock(MockClientState), } @@ -171,7 +171,7 @@ impl AnyClientState { match self { Self::Tendermint(tm_state) => tm_state.latest_height(), - #[cfg(test)] + #[cfg(any(test, feature = "mocks"))] Self::Mock(mock_state) => mock_state.latest_height(), } } @@ -179,7 +179,7 @@ impl AnyClientState { match self { Self::Tendermint(state) => state.client_type(), - #[cfg(test)] + #[cfg(any(test, feature = "mocks"))] Self::Mock(state) => state.client_type(), } } @@ -198,7 +198,7 @@ impl TryFrom for AnyClientState { .map_err(|e| Kind::InvalidRawClientState.context(e))?, )), - #[cfg(test)] + #[cfg(any(test, feature = "mocks"))] MOCK_CLIENT_STATE_TYPE_URL => Ok(AnyClientState::Mock( MockClientState::decode_vec(&raw.value) .map_err(|e| Kind::InvalidRawClientState.context(e))?, @@ -216,7 +216,7 @@ impl From for Any { type_url: TENDERMINT_CLIENT_STATE_TYPE_URL.to_string(), value: value.encode_vec().unwrap(), }, - #[cfg(test)] + #[cfg(any(test, feature = "mocks"))] AnyClientState::Mock(value) => Any { type_url: MOCK_CLIENT_STATE_TYPE_URL.to_string(), value: value.encode_vec().unwrap(), @@ -242,7 +242,7 @@ impl ClientState for AnyClientState { match self { AnyClientState::Tendermint(tm_state) => tm_state.is_frozen(), - #[cfg(test)] + #[cfg(any(test, feature = "mocks"))] AnyClientState::Mock(mock_state) => mock_state.is_frozen(), } } @@ -252,7 +252,7 @@ impl ClientState for AnyClientState { pub enum AnyConsensusState { Tendermint(crate::ics07_tendermint::consensus_state::ConsensusState), - #[cfg(test)] + #[cfg(any(test, feature = "mocks"))] Mock(MockConsensusState), } @@ -261,7 +261,7 @@ impl AnyConsensusState { match self { AnyConsensusState::Tendermint(_cs) => ClientType::Tendermint, - #[cfg(test)] + #[cfg(any(test, feature = "mocks"))] AnyConsensusState::Mock(_cs) => ClientType::Mock, } } @@ -279,7 +279,7 @@ impl TryFrom for AnyConsensusState { .map_err(|e| Kind::InvalidRawConsensusState.context(e))?, )), - #[cfg(test)] + #[cfg(any(test, feature = "mocks"))] MOCK_CONSENSUS_STATE_TYPE_URL => Ok(AnyConsensusState::Mock( MockConsensusState::decode_vec(&value.value) .map_err(|e| Kind::InvalidRawConsensusState.context(e))?, @@ -297,7 +297,7 @@ impl From for Any { type_url: TENDERMINT_CONSENSUS_STATE_TYPE_URL.to_string(), value: value.encode_vec().unwrap(), }, - #[cfg(test)] + #[cfg(any(test, feature = "mocks"))] AnyConsensusState::Mock(value) => Any { type_url: MOCK_CONSENSUS_STATE_TYPE_URL.to_string(), value: value.encode_vec().unwrap(), @@ -324,7 +324,7 @@ impl ConsensusState for AnyConsensusState { pub enum AnyClient { Tendermint(TendermintClient), - #[cfg(test)] + #[cfg(any(test, feature = "mocks"))] Mock(MockClient), } @@ -333,7 +333,7 @@ impl AnyClient { match client_type { ClientType::Tendermint => Self::Tendermint(TendermintClient), - #[cfg(test)] + #[cfg(any(test, feature = "mocks"))] ClientType::Mock => Self::Mock(MockClient), } } @@ -367,7 +367,7 @@ impl ClientDef for AnyClient { )) } - #[cfg(test)] + #[cfg(any(test, feature = "mocks"))] Self::Mock(client) => { let (client_state, header) = downcast!( client_state => AnyClientState::Mock, @@ -414,7 +414,7 @@ impl ClientDef for AnyClient { ) } - #[cfg(test)] + #[cfg(any(test, feature = "mocks"))] Self::Mock(client) => { let client_state = downcast!( client_state => AnyClientState::Mock @@ -458,7 +458,7 @@ impl ClientDef for AnyClient { ) } - #[cfg(test)] + #[cfg(any(test, feature = "mocks"))] Self::Mock(client) => { let client_state = downcast!(client_state => AnyClientState::Mock) .ok_or_else(|| Kind::ClientArgsTypeMismatch(ClientType::Mock))?; @@ -503,7 +503,7 @@ impl ClientDef for AnyClient { ) } - #[cfg(test)] + #[cfg(any(test, feature = "mocks"))] Self::Mock(client) => { let client_state = downcast!( client_state => AnyClientState::Mock diff --git a/modules/src/ics02_client/client_type.rs b/modules/src/ics02_client/client_type.rs index fa61c5c7ce..ad0e006de8 100644 --- a/modules/src/ics02_client/client_type.rs +++ b/modules/src/ics02_client/client_type.rs @@ -6,7 +6,7 @@ use serde_derive::{Deserialize, Serialize}; pub enum ClientType { Tendermint = 1, - #[cfg(test)] + #[cfg(any(test, feature = "mocks"))] Mock = 9999, } @@ -16,7 +16,7 @@ impl ClientType { match self { Self::Tendermint => "Tendermint", - #[cfg(test)] + #[cfg(any(test, feature = "mocks"))] Self::Mock => "mock", } } @@ -29,7 +29,7 @@ impl std::str::FromStr for ClientType { match s { "Tendermint" => Ok(Self::Tendermint), - #[cfg(test)] + #[cfg(any(test, feature = "mocks"))] "mock" => Ok(Self::Mock), _ => Err(error::Kind::UnknownClientType(s.to_string()).into()), diff --git a/modules/src/ics18_relayer/context.rs b/modules/src/ics18_relayer/context.rs index 4213089f83..dfa7751c7e 100644 --- a/modules/src/ics18_relayer/context.rs +++ b/modules/src/ics18_relayer/context.rs @@ -4,6 +4,8 @@ use crate::ics24_host::identifier::ClientId; use crate::ics26_routing::msgs::ICS26Envelope; use crate::Height; +use tendermint::account::Id as AccountId; + /// Trait capturing all dependencies (i.e., the context) which algorithms in ICS18 require to /// relay packets between chains. This trait comprises the dependencies towards a single chain. /// Most of the functions in this represent wrappers over the ABCI interface. @@ -22,4 +24,7 @@ pub trait ICS18Context { /// Interface that the relayer uses to submit a datagram to this chain. /// Wraps around the `/broadcast_tx_async` ABCI endpoint. fn send(&mut self, msg: ICS26Envelope) -> Result<(), Error>; + + /// Temporary solution. Similar to `CosmosSDKChain::key_and_signer()` but simpler. + fn signer(&self) -> AccountId; } diff --git a/modules/src/ics18_relayer/mod.rs b/modules/src/ics18_relayer/mod.rs index 9f502c98f1..71e8e42ed9 100644 --- a/modules/src/ics18_relayer/mod.rs +++ b/modules/src/ics18_relayer/mod.rs @@ -3,5 +3,4 @@ pub mod context; pub mod error; -#[cfg(test)] -pub mod utils; // Currently only used in tests. +pub mod utils; diff --git a/modules/src/ics18_relayer/utils.rs b/modules/src/ics18_relayer/utils.rs index d585be83d2..719de09f46 100644 --- a/modules/src/ics18_relayer/utils.rs +++ b/modules/src/ics18_relayer/utils.rs @@ -5,7 +5,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::test_utils::get_dummy_account_id; /// Creates 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`. @@ -47,7 +46,7 @@ where Ok(ClientMsg::UpdateClient(MsgUpdateAnyClient { client_id: client_id.clone(), header: src_header, - signer: get_dummy_account_id(), + signer: dest.signer(), })) } diff --git a/modules/src/lib.rs b/modules/src/lib.rs index 04577d5760..8efbe3a0df 100644 --- a/modules/src/lib.rs +++ b/modules/src/lib.rs @@ -38,7 +38,7 @@ pub mod macros; pub mod proofs; pub mod tx_msg; -#[cfg(test)] +#[cfg(any(test, feature = "mocks"))] pub mod mock_client; /// Re-export of ICS 002 Height domain type @@ -50,5 +50,5 @@ mod test; #[cfg(test)] mod test_utils; -#[cfg(test)] -mod mock_context; // Context mock: for testing all handlers. +#[cfg(any(test, feature = "mocks"))] +pub mod mock_context; // Context mock: for testing all handlers. diff --git a/modules/src/mock_context.rs b/modules/src/mock_context.rs index f87a2d3deb..402b49ebaa 100644 --- a/modules/src/mock_context.rs +++ b/modules/src/mock_context.rs @@ -23,6 +23,8 @@ use crate::Height; use std::cmp::min; use std::collections::HashMap; use std::error::Error; +use std::str::FromStr; +use tendermint::account::Id; #[derive(Clone, Debug)] pub struct MockContext { @@ -374,6 +376,10 @@ impl ICS18Context for MockContext { fn send(&mut self, msg: ICS26Envelope) -> Result<(), ICS18Error> { self.recv(msg) } + + fn signer(&self) -> Id { + Id::from_str("0CDA3F47EF3C4906693B170EF650EB968C5F4B2C").unwrap() + } } #[cfg(test)]