Skip to content

Commit

Permalink
Local chain implementation & basic tests (informalsystems#422)
Browse files Browse the repository at this point in the history
* Attemptin integration at the level of Chain trait

* Removed rpc client from trait Chain

* Removed ChainConfig from trait Chain

* Minor fixes as follow-up from informalsystems#364

* Impl generic runtime instantiation.

* Migrated CLIs to use generic runtime spawn.

* Added mock light client. First test (incomplete impl).

* Almost ready to send_tx (mock has to be mutable).

* Added chain executor.

* Mutable chain in send_tx, simplified spawn.After review w/ Anca & Romain

* impl CosmosSDKChain cleanup

* Adapted mock context, ICS18 & 26 to correct abstractions.

* Cleaned up Msg trait, added const TYPE_URL.

* Basic light client impl to complete create client test.

* Removed clippy allow exception

* Updated changelog

* Revert "Updated changelog"

This reverts commit 43bd008.
In anticipation of merging master into this dev branch..

* Redid the changelog

* After Anca's comments
  • Loading branch information
adizere authored Dec 3, 2020
1 parent a331834 commit cfa1e18
Show file tree
Hide file tree
Showing 21 changed files with 576 additions and 199 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@

## Unreleased Changes

### FEATURES

### IMPROVEMENTS

- Mock chain (implementing IBC handlers) and integration against CLI ([#158])

[#158]: https://github.com/informalsystems/ibc-rs/issues/158

## v0.0.5
*December 2, 2020*
Expand Down
2 changes: 1 addition & 1 deletion relayer-cli/src/commands/query/channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ impl Runnable for QueryChannelEndCmd {

let rt = Arc::new(Mutex::new(TokioRuntime::new().unwrap()));

let chain = CosmosSDKChain::from_config(chain_config, rt).unwrap();
let chain = CosmosSDKChain::bootstrap(chain_config, rt).unwrap();
let height = ibc::Height::new(chain.id().version(), opts.height);
let res: Result<ChannelEnd, Error> = chain
.query(
Expand Down
6 changes: 3 additions & 3 deletions relayer-cli/src/commands/query/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ impl Runnable for QueryClientStateCmd {
status_info!("Options", "{:?}", opts);

let rt = Arc::new(Mutex::new(TokioRuntime::new().unwrap()));
let chain = CosmosSDKChain::from_config(chain_config, rt).unwrap();
let chain = CosmosSDKChain::bootstrap(chain_config, rt).unwrap();
let height = ibc::Height::new(chain.id().version(), opts.height);

let res: Result<AnyClientState, Error> = chain
Expand Down Expand Up @@ -172,7 +172,7 @@ impl Runnable for QueryClientConsensusCmd {
status_info!("Options", "{:?}", opts);

let rt = Arc::new(Mutex::new(TokioRuntime::new().unwrap()));
let chain = CosmosSDKChain::from_config(chain_config, rt).unwrap();
let chain = CosmosSDKChain::bootstrap(chain_config, rt).unwrap();
let height = ibc::Height::new(chain.id().version(), opts.height);

let res: Result<AnyConsensusState, Error> = chain
Expand Down Expand Up @@ -286,7 +286,7 @@ impl Runnable for QueryClientConnectionsCmd {
status_info!("Options", "{:?}", opts);

let rt = Arc::new(Mutex::new(TokioRuntime::new().unwrap()));
let chain = CosmosSDKChain::from_config(chain_config, rt).unwrap();
let chain = CosmosSDKChain::bootstrap(chain_config, rt).unwrap();
let height = ibc::Height::new(chain.id().version(), opts.height);

let res: Result<ConnectionIDs, Error> = chain
Expand Down
2 changes: 1 addition & 1 deletion relayer-cli/src/commands/query/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ impl Runnable for QueryConnectionEndCmd {
status_info!("Options", "{:?}", opts);

let rt = Arc::new(Mutex::new(TokioRuntime::new().unwrap()));
let chain = CosmosSDKChain::from_config(chain_config, rt).unwrap();
let chain = CosmosSDKChain::bootstrap(chain_config, rt).unwrap();
let height = ibc::Height::new(chain.id().version(), opts.height);

// TODO - any value in querying with proof from the CLI?
Expand Down
7 changes: 5 additions & 2 deletions relayer-cli/src/commands/tx/channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use relayer::channel::{
};

use relayer::chain::runtime::ChainRuntime;
use relayer::chain::CosmosSDKChain;
use relayer::channel::{ChannelConfig, ChannelConfigSide};

macro_rules! chan_open_cmd {
Expand Down Expand Up @@ -86,8 +87,10 @@ macro_rules! chan_open_cmd {

status_info!("Message ", "{}: {:#?}", $dbg_string, opts);

let (src_chain, _) = ChainRuntime::spawn(src_chain_config.clone()).unwrap();
let (dst_chain, _) = ChainRuntime::spawn(dst_chain_config.clone()).unwrap();
let (src_chain, _) =
ChainRuntime::<CosmosSDKChain>::spawn(src_chain_config.clone()).unwrap();
let (dst_chain, _) =
ChainRuntime::<CosmosSDKChain>::spawn(dst_chain_config.clone()).unwrap();

let res: Result<String, Error> =
$func(dst_chain, src_chain, &opts).map_err(|e| Kind::Tx.context(e).into());
Expand Down
9 changes: 5 additions & 4 deletions relayer-cli/src/commands/tx/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use crate::application::app_config;
use crate::error::{Error, Kind};
use crate::prelude::*;
use relayer::chain::runtime::ChainRuntime;
use relayer::chain::CosmosSDKChain;
use relayer::config::ChainConfig;
use relayer::foreign_client::{
build_create_client_and_send, build_update_client_and_send, ForeignClientConfig,
Expand Down Expand Up @@ -48,8 +49,8 @@ impl Runnable for TxCreateClientCmd {
opts.chain_id()
);

let (src_chain, _) = ChainRuntime::spawn(src_chain_config).unwrap();
let (dst_chain, _) = ChainRuntime::spawn(dst_chain_config).unwrap();
let (src_chain, _) = ChainRuntime::<CosmosSDKChain>::spawn(src_chain_config).unwrap();
let (dst_chain, _) = ChainRuntime::<CosmosSDKChain>::spawn(dst_chain_config).unwrap();

let res: Result<String, Error> = build_create_client_and_send(dst_chain, src_chain, &opts)
.map_err(|e| Kind::Tx.context(e).into());
Expand Down Expand Up @@ -97,8 +98,8 @@ impl Runnable for TxUpdateClientCmd {
opts.chain_id()
);

let (src_chain, _) = ChainRuntime::spawn(src_chain_config).unwrap();
let (dst_chain, _) = ChainRuntime::spawn(dst_chain_config).unwrap();
let (src_chain, _) = ChainRuntime::<CosmosSDKChain>::spawn(src_chain_config).unwrap();
let (dst_chain, _) = ChainRuntime::<CosmosSDKChain>::spawn(dst_chain_config).unwrap();

let res: Result<String, Error> = build_update_client_and_send(dst_chain, src_chain, &opts)
.map_err(|e| Kind::Tx.context(e).into());
Expand Down
7 changes: 5 additions & 2 deletions relayer-cli/src/commands/tx/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use relayer::connection::{

use crate::error::{Error, Kind};
use relayer::chain::runtime::ChainRuntime;
use relayer::chain::CosmosSDKChain;
use relayer::connection::{ConnectionConfig, ConnectionSideConfig};

macro_rules! conn_open_cmd {
Expand Down Expand Up @@ -75,8 +76,10 @@ macro_rules! conn_open_cmd {

status_info!("Message ", "{}: {:#?}", $dbg_string, opts);

let (src_chain, _) = ChainRuntime::spawn(src_chain_config.clone()).unwrap();
let (dst_chain, _) = ChainRuntime::spawn(dst_chain_config.clone()).unwrap();
let (src_chain, _) =
ChainRuntime::<CosmosSDKChain>::spawn(src_chain_config.clone()).unwrap();
let (dst_chain, _) =
ChainRuntime::<CosmosSDKChain>::spawn(dst_chain_config.clone()).unwrap();

let res: Result<String, Error> =
$func(dst_chain, src_chain, &opts).map_err(|e| Kind::Tx.context(e).into());
Expand Down
5 changes: 3 additions & 2 deletions relayer-cli/src/commands/v0.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use relayer::relay::channel_relay;

use crate::config::Config;
use crate::prelude::*;
use relayer::chain::CosmosSDKChain;

#[derive(Command, Debug, Options)]
pub struct V0Cmd {}
Expand Down Expand Up @@ -57,8 +58,8 @@ pub fn v0_task(config: &Config) -> Result<(), BoxError> {
.find(|c| c.id == connection.dst().chain_id().clone())
.ok_or("Configuration for source chain not found")?;

let (src_chain_handle, _) = ChainRuntime::spawn(src_chain_config)?;
let (dst_chain_handle, _) = ChainRuntime::spawn(dst_chain_config)?;
let (src_chain_handle, _) = ChainRuntime::<CosmosSDKChain>::spawn(src_chain_config)?;
let (dst_chain_handle, _) = ChainRuntime::<CosmosSDKChain>::spawn(dst_chain_config)?;

Ok(channel_relay(
src_chain_handle,
Expand Down
2 changes: 1 addition & 1 deletion relayer-cli/tests/integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ fn simd_config() -> Config {
/// Chain created for the informaldev/simd DockerHub image running on localhost.
fn simd_chain() -> CosmosSDKChain {
let rt = Arc::new(Mutex::new(tokio::runtime::Runtime::new().unwrap()));
CosmosSDKChain::from_config(simd_config().chains[0].clone(), rt).unwrap()
CosmosSDKChain::bootstrap(simd_config().chains[0].clone(), rt).unwrap()
}

/// Query connection ID. Requires the informaldev/simd Docker image running on localhost.
Expand Down
2 changes: 2 additions & 0 deletions relayer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,5 @@ version = "=0.17.0-rc3"

[dev-dependencies]
serial_test = "0.5.0"
ibc = { path = "../modules", features = [ "mocks" ] }
tendermint-testgen = { version = "0.17.0-rc3" }
58 changes: 36 additions & 22 deletions relayer/src/chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,16 @@ pub use cosmos::CosmosSDKChain;
pub mod handle;
pub mod runtime;

#[cfg(test)]
pub mod mock;

use crossbeam_channel as channel;
use std::{
sync::{Arc, Mutex},
thread,
};
use tokio::runtime::Runtime as TokioRuntime;

use prost_types::Any;

use tendermint_proto::Protobuf;
Expand All @@ -12,8 +22,6 @@ use tendermint_proto::Protobuf;
use tendermint::account::Id as AccountId;
use tendermint::block::Height;

use tendermint_rpc::Client as RpcClient;

use ibc::ics02_client::header::Header;

use ibc::ics02_client::state::{ClientState, ConsensusState};
Expand All @@ -33,7 +41,9 @@ use ibc::Height as ICSHeight;
use crate::config::ChainConfig;
use crate::connection::ConnectionMsgType;
use crate::error::{Error, Kind};
use crate::event::monitor::EventBatch;
use crate::keyring::store::{KeyEntry, KeyRing};
use crate::light_client::LightClient;

/// Generic query response type
/// TODO - will slowly move to GRPC protobuf specs for queries
Expand All @@ -45,7 +55,7 @@ pub struct QueryResponse {
}

/// Defines a blockchain as understood by the relayer
pub trait Chain {
pub trait Chain: Sized {
/// Type of light blocks for this chain
type LightBlock: Send + Sync;

Expand All @@ -58,29 +68,38 @@ pub trait Chain {
/// Type of the client state for this chain
type ClientState: ClientState;

/// Type of RPC requester (wrapper around low-level RPC client) for this chain
type RpcClient: RpcClient + Send + Sync;
/// Constructs the chain
fn bootstrap(config: ChainConfig, rt: Arc<Mutex<TokioRuntime>>) -> Result<Self, Error>;

/// Returns the chain's identifier
fn id(&self) -> &ChainId {
&self.config().id
}
#[allow(clippy::type_complexity)]
/// Initializes and returns the light client (if any) associated with this chain.
fn init_light_client(
&self,
) -> Result<(Box<dyn LightClient<Self>>, Option<thread::JoinHandle<()>>), Error>;

/// Returns the chain's configuration
fn config(&self) -> &ChainConfig;
/// Initializes and returns the event monitor (if any) associated with this chain.
fn init_event_monitor(
&self,
rt: Arc<Mutex<TokioRuntime>>,
) -> Result<
(
channel::Receiver<EventBatch>,
Option<thread::JoinHandle<()>>,
),
Error,
>;

/// Returns the chain's identifier
fn id(&self) -> &ChainId;

/// Returns the chain's keybase
fn keybase(&self) -> &KeyRing;

/// Get a low-level RPC client for this chain
/// TODO - Should this be part of the Chain trait?
fn rpc_client(&self) -> &Self::RpcClient;

/// Perform a generic ICS `query`, and return the corresponding response data.
fn query(&self, data: Path, height: ICSHeight, prove: bool) -> Result<QueryResponse, Error>;

/// Send a transaction with `msgs` to chain.
fn send_tx(&self, proto_msgs: Vec<Any>) -> Result<String, Error>;
fn send_tx(&mut self, proto_msgs: Vec<Any>) -> Result<String, Error>;

fn get_signer(&mut self) -> Result<AccountId, Error>;

Expand Down Expand Up @@ -111,12 +130,7 @@ pub trait Chain {
height: ICSHeight,
) -> Result<Self::ClientState, Error>;

fn query_commitment_prefix(&self) -> Result<CommitmentPrefix, Error> {
// TODO - do a real chain query
Ok(CommitmentPrefix::from(
self.config().store_prefix.as_bytes().to_vec(),
))
}
fn query_commitment_prefix(&self) -> Result<CommitmentPrefix, Error>;

fn query_compatible_versions(&self) -> Result<Vec<String>, Error> {
// TODO - do a real chain query
Expand Down
Loading

0 comments on commit cfa1e18

Please sign in to comment.