Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add client queries to the relayer #38

Merged
merged 16 commits into from
Apr 10, 2020
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions modules/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,7 @@ anomaly = "0.2.0"
thiserror = "1.0.11"
serde_derive = "1.0.104"
serde = "1.0.104"

[dev-dependencies]
serde_json = "1"

22 changes: 22 additions & 0 deletions modules/src/ics02_client/state.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use super::client_type::ClientType;

use crate::ics23_commitment::CommitmentRoot;
use crate::ics24_host::client::ClientId;
use crate::Height;

pub trait ConsensusState {
Expand All @@ -18,3 +19,24 @@ pub trait ConsensusState {
/// Performs basic validation of the consensus state
fn validate_basic(&self) -> Result<(), Self::ValidationError>;
}

pub trait ClientState {
type ValidationError: std::error::Error;

/// Client ID of this state
fn client_id(&self) -> ClientId;

/// Type of client associated with this state (eg. Tendermint)
fn client_type(&self) -> ClientType;

/// Height of consensus state
fn get_latest_height(&self) -> Height;

/// Freeze status of the client
fn is_frozen(&self) -> bool;

fn verify_client_consensus_state(
&self,
root: &CommitmentRoot,
) -> Result<(), Self::ValidationError>;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, a bit more work to get there :)

}
82 changes: 82 additions & 0 deletions modules/src/ics07_tendermint/client_state.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
use crate::ics02_client::client_type::ClientType;
use crate::ics23_commitment::CommitmentRoot;

use crate::ics07_tendermint::header::Header;
use crate::ics24_host::client::ClientId;
use serde_derive::{Deserialize, Serialize};
use std::time::Duration;
use tendermint::lite::Header as liteHeader;

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct ClientState {
id: String,
trusting_period: Duration,
Copy link
Member

@liamsi liamsi Apr 3, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note (mostly to myself):

in the go code, time.Duration actually is this type alias:

// A Duration represents the elapsed time between two instants
// as an int64 nanosecond count. The representation limits the
// largest representable duration to approximately 290 years.
type Duration int64

while rust's std::time::Duration actually is

/// A `Duration` type to represent a span of time, typically used for system
/// timeouts.
///
/// Each `Duration` is composed of a whole number of seconds and a fractional part
/// represented in nanoseconds. If the underlying system does not support
/// nanosecond-level precision, APIs binding a system timeout will typically round up
/// the number of nanoseconds.
/// [...]
pub struct Duration {
    secs: u64,
    nanos: u32, // Always 0 <= nanos < NANOS_PER_SEC
}

Same for the unbonding_period field below.

So for deserialization (independent from amino or not) we need to translate between the two.

ref #45

unbonding_period: Duration,
latest_header: Header,
Copy link
Member

@liamsi liamsi Apr 6, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that the Header here contains a SignedHeader which in turn contains a Commit. Looking at the Commit struct in the iqlusion/relayer (on master) shows that they are already using tendermint v0.33.2 which modified the Commit struct to:

type Commit struct {
	// NOTE: The signatures are in order of address to preserve the bonded
	// ValidatorSet order.
	// Any peer with a block can gossip signatures by index with a peer without
	// recalculating the active ValidatorSet.
	Height     int64       `json:"height"`
	Round      int         `json:"round"`
	BlockID    BlockID     `json:"block_id"`
	Signatures []CommitSig `json:"signatures"`
        // ...
}

while this branch uses the v0.32 version of the Commit:

pub struct Commit {
    /// Block ID of the last commit
    pub block_id: block::Id,

    /// Precommits
    pub precommits: Precommits,
}

Or in golang (from v0.32.x): https://github.com/tendermint/tendermint/blob/64e61365c16f74d56ccaa9eb784e05df5b01764c/types/block.go#L489-L494

v0.33 tendermint-rs is currently worked on in informalsystems/tendermint-rs#196

Does it make sense to assume we want to decode v0.33 commits directly (for the sake of #45)? @ancazamfir

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, let's look at 0.33! thx!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only commit batched together with the suggestion below (frozen_height):

Suggested change
latest_header: Header,

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

frozen_height: crate::Height,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The order in the go-code is different (latest header should be last):

Suggested change
frozen_height: crate::Height,
frozen_height: crate::Height,
latest_header: Header,

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oy! good catch! thx, just changed. The problem is that we cannot test properly with SDK since we don't deserialize yet. Once we move to protobuf and we do the decoding we will catch more of these.

}

impl ClientState {
pub fn new(
id: String,
trusting_period: Duration,
unbonding_period: Duration,
latest_header: Header,
frozen_height: crate::Height,
) -> Self {
Self {
id,
trusting_period,
unbonding_period,
latest_header,
frozen_height,
}
}
}

impl crate::ics02_client::state::ClientState for ClientState {
type ValidationError = crate::ics07_tendermint::error::Error;

fn client_id(&self) -> ClientId {
self.id.parse().unwrap()
}

fn client_type(&self) -> ClientType {
ClientType::Tendermint
}

fn get_latest_height(&self) -> crate::Height {
self.latest_header.signed_header.header.height()
}

fn is_frozen(&self) -> bool {
false
}

fn verify_client_consensus_state(
&self,
_root: &CommitmentRoot,
) -> Result<(), Self::ValidationError> {
unimplemented!()
}
}

#[cfg(test)]
mod tests {
use crate::test::test_serialization_roundtrip;
use tendermint::rpc::endpoint::abci_query::AbciQuery;

#[test]
fn serialization_roundtrip_no_proof() {
let json_data = include_str!("../tests/query/serialization/client_state.json");
println!("json_data: {:?}", json_data);
test_serialization_roundtrip::<AbciQuery>(json_data);
}

#[test]
fn serialization_roundtrip_with_proof() {
let json_data = include_str!("../tests/query/serialization/client_state_proof.json");
println!("json_data: {:?}", json_data);
test_serialization_roundtrip::<AbciQuery>(json_data);
}
}
20 changes: 20 additions & 0 deletions modules/src/ics07_tendermint/consensus_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,23 @@ impl crate::ics02_client::state::ConsensusState for ConsensusState {
unimplemented!()
}
}

#[cfg(test)]
mod tests {
use crate::test::test_serialization_roundtrip;
use tendermint::rpc::endpoint::abci_query::AbciQuery;

#[test]
fn serialization_roundtrip_no_proof() {
let json_data = include_str!("../tests/query/serialization/consensus_state.json");
println!("json_data: {:?}", json_data);
test_serialization_roundtrip::<AbciQuery>(json_data);
}

#[test]
fn serialization_roundtrip_with_proof() {
let json_data = include_str!("../tests/query/serialization/consensus_state_proof.json");
println!("json_data: {:?}", json_data);
test_serialization_roundtrip::<AbciQuery>(json_data);
}
}
1 change: 1 addition & 0 deletions modules/src/ics07_tendermint/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//! ICS 07: Tendermint Client

pub mod client_state;
pub mod consensus_state;
pub mod error;
pub mod header;
Expand Down
3 changes: 3 additions & 0 deletions modules/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,6 @@ pub mod path;

/// Height of a block, same as in `tendermint` crate
pub type Height = tendermint::lite::Height;

#[cfg(test)]
mod test;
16 changes: 16 additions & 0 deletions modules/src/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,19 @@ impl Path for ConsensusStatePath {
paths::consensus_state_path(&self)
}
}

pub struct ClientStatePath {
pub client_id: ClientId,
}

impl ClientStatePath {
pub fn new(client_id: ClientId) -> Self {
Self { client_id }
}
}

impl Path for ClientStatePath {
fn to_string(&self) -> String {
paths::client_state_path(&self)
}
}
6 changes: 5 additions & 1 deletion modules/src/path/cosmos.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::{ConnectionPath, ConsensusStatePath};
use super::{ClientStatePath, ConnectionPath, ConsensusStatePath};

pub fn connection_path(path: &ConnectionPath) -> String {
format!("connection/{}", path.connection_id)
Expand All @@ -7,3 +7,7 @@ pub fn connection_path(path: &ConnectionPath) -> String {
pub fn consensus_state_path(path: &ConsensusStatePath) -> String {
format!("consensusState/{}/{}", path.client_id, path.height)
}

pub fn client_state_path(path: &ClientStatePath) -> String {
format!("clientState/{}", path.client_id)
}
6 changes: 5 additions & 1 deletion modules/src/path/ics.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::{ConnectionPath, ConsensusStatePath};
use super::{ClientStatePath, ConnectionPath, ConsensusStatePath};

pub fn connection_path(_path: &ConnectionPath) -> String {
todo!()
Expand All @@ -7,3 +7,7 @@ pub fn connection_path(_path: &ConnectionPath) -> String {
pub fn consensus_state_path(_path: &ConsensusStatePath) -> String {
todo!()
}

pub fn client_state_path(_path: &ClientStatePath) -> String {
todo!()
}
30 changes: 30 additions & 0 deletions modules/src/test.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
use serde::{de::DeserializeOwned, Serialize};
use std::fmt::Debug;

/// Test that a struct `T` can be:
///
/// - parsed out of the provided JSON data
/// - serialized back to JSON
/// - parsed back from the serialized JSON of the previous step
/// - that the two parsed structs are equal according to their `PartialEq` impl
pub fn test_serialization_roundtrip<T>(json_data: &str)
where
T: Debug + Serialize + DeserializeOwned,
{
let parsed0 = serde_json::from_str::<T>(json_data);
assert!(parsed0.is_ok());
let parsed0 = parsed0.unwrap();

let serialized = serde_json::to_string(&parsed0);
assert!(serialized.is_ok());
let serialized = serialized.unwrap();

let parsed1 = serde_json::from_str::<T>(&serialized);
assert!(parsed1.is_ok());
let parsed1 = parsed1.unwrap();
println!("json_data0: {:?}", parsed0);
println!("json_data1: {:?}", parsed1);

// TODO - fix PartialEq bound issue in AbciQuery
//assert_eq!(parsed0, parsed1);
}
11 changes: 11 additions & 0 deletions modules/src/tests/query/serialization/client_state.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"code": 0,
"log": "",
"info": "",
"index": "0",
"key": "Y2xpZW50U3RhdGUvaWJjb25lY2xpZW50",
"value": "rwUhoYiWCgxpYmNvbmVjbGllbnQQgIDIkv+DkwIYgIDs2/7FnAMqiAUKgAQKxQIKAggKEgRpYmMxGBYiCwjMvIL0BRDIu58kKkgKICyeWhXpKZwrrUlzbaZ0DQnPqzkdNc8+k9eOogSLx43aEiQIARIgCFeoy6YD9BwuE0C1AU9BdEa2V51Cs28MXKewBA1rNtMyIBNgBAObhFbZAWB4KQGBQaC7Z/azZUkkSj2hMdZFFFppQiDses9b3+5uOFW4wZL6WWA0xtv9hTPe3Ib6BA7pzYQySUog7HrPW9/ubjhVuMGS+llgNMbb/YUz3tyG+gQO6c2EMklSIASAkbx93Cg/d7+/kdc8RNpYw9+KnLyGdAXYt/ParaIvWiBq+Q9GJMZNlWMQCpPikuUo+bJNzOKyjZSthVT8qdTQRmIgbjQLnP+zepicpUTmu3gKLHiQHT+zNzh2hRGjBhevoB1yFPbqil8EwnDU5G93rMLZvekApgKBErUBCBYaSAogZik4C8oy55EdSL4OhMTIAy8jsDvCYiK6ZYH58Wv6Q88SJAgBEiBIpIMYxWV2OFZh72/ooILjIPvaHEMZ008+w1h+rpi7WiJnCAISFPbqil8EwnDU5G93rMLZvekApgKBGgsIzbyC9AUQqI/hRyJAbloumBKmq9nNQ22y/XoogOCrp33xeHjzA2JyuxpR2oAtL+8KGwKbcCJvAZjwpqOEEiRdXJnQ1rHrubVJhg3WBRKCAQo/ChT26opfBMJw1ORvd6zC2b3pAKYCgRIlFiTeZCBdmybLcqCWKo8EBc9ZOM+rYKVUx4QmxhMYv93tBdcNDxhkEj8KFPbqil8EwnDU5G93rMLZvekApgKBEiUWJN5kIF2bJstyoJYqjwQFz1k4z6tgpVTHhCbGExi/3e0F1w0PGGQ=",
"proof": null,
"height": "100",
"codespace": ""
}
24 changes: 24 additions & 0 deletions modules/src/tests/query/serialization/client_state_proof.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"code": 0,
"log": "",
"info": "",
"index": "0",
"key": "Y2xpZW50U3RhdGUvaWJjb25lY2xpZW50",
"value": "rwUhoYiWCgxpYmNvbmVjbGllbnQQgIDIkv+DkwIYgIDs2/7FnAMqiAUKgAQKxQIKAggKEgRpYmMxGBYiCwjMvIL0BRDIu58kKkgKICyeWhXpKZwrrUlzbaZ0DQnPqzkdNc8+k9eOogSLx43aEiQIARIgCFeoy6YD9BwuE0C1AU9BdEa2V51Cs28MXKewBA1rNtMyIBNgBAObhFbZAWB4KQGBQaC7Z/azZUkkSj2hMdZFFFppQiDses9b3+5uOFW4wZL6WWA0xtv9hTPe3Ib6BA7pzYQySUog7HrPW9/ubjhVuMGS+llgNMbb/YUz3tyG+gQO6c2EMklSIASAkbx93Cg/d7+/kdc8RNpYw9+KnLyGdAXYt/ParaIvWiBq+Q9GJMZNlWMQCpPikuUo+bJNzOKyjZSthVT8qdTQRmIgbjQLnP+zepicpUTmu3gKLHiQHT+zNzh2hRGjBhevoB1yFPbqil8EwnDU5G93rMLZvekApgKBErUBCBYaSAogZik4C8oy55EdSL4OhMTIAy8jsDvCYiK6ZYH58Wv6Q88SJAgBEiBIpIMYxWV2OFZh72/ooILjIPvaHEMZ008+w1h+rpi7WiJnCAISFPbqil8EwnDU5G93rMLZvekApgKBGgsIzbyC9AUQqI/hRyJAbloumBKmq9nNQ22y/XoogOCrp33xeHjzA2JyuxpR2oAtL+8KGwKbcCJvAZjwpqOEEiRdXJnQ1rHrubVJhg3WBRKCAQo/ChT26opfBMJw1ORvd6zC2b3pAKYCgRIlFiTeZCBdmybLcqCWKo8EBc9ZOM+rYKVUx4QmxhMYv93tBdcNDxhkEj8KFPbqil8EwnDU5G93rMLZvekApgKBEiUWJN5kIF2bJstyoJYqjwQFz1k4z6tgpVTHhCbGExi/3e0F1w0PGGQ=",
"proof": {
"ops": [
{
"type": "iavl:v",
"key": "Y2xpZW50U3RhdGUvaWJjb25lY2xpZW50",
"data": "6wEK6AEKKAgIEAwYHCogr722bXSL9572EU1Jgdz6re1sVtpscxSW4cjaLrCtKPoKKAgGEAcYHCIg1wO/S0DOyBX5/zwOTIQt5lY7SkEJUORfEfZtHH6ZcLcKKAgEEAQYHCIgvBVVJn1U3LKVuitwm6hAvnwujQDcyMOOp5YdNbwdyTEKKAgCEAIYFyIgcuZfF//lb+VDAKtkXsR/J2/QPYlaw8HvrSmNqDf1iVYaPgoYY2xpZW50U3RhdGUvaWJjb25lY2xpZW50EiDV6DHA5N7GJNbSj0hzc586MXPwXDj4H57rYWZesk2XjRgX"
},
{
"type": "multistore",
"key": "aWJj",
"data": "CtUECi4KBGJhbmsSJgokCGQSIPfIBFZd98DupWwTml7I8kZFWKgF8ZTlslblitSLTJjqCi0KA2FjYxImCiQIZBIg3ZgdzN65c2/J62tIVCmQJwnN8Ho9dULDSL9dKEyA+cgKDwoHdXBncmFkZRIECgIIZAoxCgdzdGFraW5nEiYKJAhkEiCWTzW3aCWkLAyuZxi9z2CSXhmtmcRWEKi6K9ywkrVZMwoyCghzbGFzaGluZxImCiQIZBIgj6AcKVZzEJeL1r3wf9Qi5B53bjomfcn3g76fvuJn/FkKMAoGc3VwcGx5EiYKJAhkEiCRsUBZCybnNEYnaNqDTOO1pNEuAfGgY7pQMrgLCyUWBQotCgNnb3YSJgokCGQSIGDNE3wZYuysYWOJ1oA0gz8pIVCcLShapfUVOZfOlop0Ci0KA2liYxImCiQIZBIgWnpokBJ4idAoXzLzbjOOaBwU5E3oz4QJuAV8mShsqzwKLgoEbWFpbhImCiQIZBIgsZzwmLQ7PH1UeZ/vCUSqlQmfgt3CGfoMgJLkUqKCv0EKMAoGcGFyYW1zEiYKJAhkEiB8VIzExUHX+SvHZFz/P9NM9THnw/gTDDLVReuZX8htLgo2CgxkaXN0cmlidXRpb24SJgokCGQSIMaSvcpnTBH1nyPp/m3Ab+A/fowTOIWmuMtlbCda/2SsChAKCHRyYW5zZmVyEgQKAghkChAKCGV2aWRlbmNlEgQKAghkCi4KBG1pbnQSJgokCGQSIPvdoKLt1qhBYkRKjo39yCkQ0c1pOYM0kohjsVVGx9ae"
}
]
},
"height": "100",
"codespace": ""
}
11 changes: 11 additions & 0 deletions modules/src/tests/query/serialization/consensus_state.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"code": 0,
"log": "",
"info": "",
"index": "0",
"key": "Y29uc2Vuc3VzU3RhdGUvaWJjb25lY2xpZW50LzIy",
"value": "wAE7xH38CgsIzLyC9AUQyLufJBImzXAxMQogavkPRiTGTZVjEAqT4pLlKPmyTcziso2UrYVU/KnU0EYYFiKCAQo/ChT26opfBMJw1ORvd6zC2b3pAKYCgRIlFiTeZCBdmybLcqCWKo8EBc9ZOM+rYKVUx4QmxhMYv93tBdcNDxhkEj8KFPbqil8EwnDU5G93rMLZvekApgKBEiUWJN5kIF2bJstyoJYqjwQFz1k4z6tgpVTHhCbGExi/3e0F1w0PGGQ=",
"proof": null,
"height": "60295",
"codespace": ""
}
24 changes: 24 additions & 0 deletions modules/src/tests/query/serialization/consensus_state_proof.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"code": 0,
"log": "",
"info": "",
"index": "0",
"key": "Y29uc2Vuc3VzU3RhdGUvaWJjb25lY2xpZW50LzIy",
"value": "wAE7xH38CgsIzLyC9AUQyLufJBImzXAxMQogavkPRiTGTZVjEAqT4pLlKPmyTcziso2UrYVU/KnU0EYYFiKCAQo/ChT26opfBMJw1ORvd6zC2b3pAKYCgRIlFiTeZCBdmybLcqCWKo8EBc9ZOM+rYKVUx4QmxhMYv93tBdcNDxhkEj8KFPbqil8EwnDU5G93rMLZvekApgKBEiUWJN5kIF2bJstyoJYqjwQFz1k4z6tgpVTHhCbGExi/3e0F1w0PGGQ=",
"proof": {
"ops": [
{
"type": "iavl:v",
"key": "Y29uc2Vuc3VzU3RhdGUvaWJjb25lY2xpZW50LzIy",
"data": "8QEK7gEKKAgIEAwYHCIgG9RAkJgHlxNjmyzOW6bUAidhiRSja0x6+GXCVENPG1oKKAgGEAUYFyIgwRns+dJvjf1Zk2BaFrXz8inPbvYHB7xx2HCy9ima5f8KKAgEEAMYFyogOr8EGajEV6fG5fzJ2fAAvVMgRLhdMJTzCPlogl9rxlIKKAgCEAIYFyIgcjzX/a+2bFbnNldpawQqZ+kYhIwz5r4wCUzuu1IFW04aRAoeY29uc2Vuc3VzU3RhdGUvaWJjb25lY2xpZW50LzIyEiAZ1uuG60K4NHJZZMuS9QX6o4eEhica5jIHYwflRiYkDBgX"
},
{
"type": "multistore",
"key": "aWJj",
"data": "CvEECjAKBGJhbmsSKAomCIjYAxIg2MEyyonbZButYnvSRkf2bPQg+nqA+Am1MeDxG6F4p1UKLwoDYWNjEigKJgiI2AMSIN2YHczeuXNvyetrSFQpkCcJzfB6PXVCw0i/XShMgPnIChEKB3VwZ3JhZGUSBgoECIjYAwovCgNnb3YSKAomCIjYAxIgYM0TfBli7KxhY4nWgDSDPykhUJwtKFql9RU5l86WinQKLwoDaWJjEigKJgiI2AMSIFp6aJASeInQKF8y824zjmgcFORN6M+ECbgFfJkobKs8CjAKBG1haW4SKAomCIjYAxIgsZzwmLQ7PH1UeZ/vCUSqlQmfgt3CGfoMgJLkUqKCv0EKMwoHc3Rha2luZxIoCiYIiNgDEiCiBZoBLyDGj5euy3n33ik+SpqYK9eB5xbI+iY8ycYVbwo0CghzbGFzaGluZxIoCiYIiNgDEiAJz3gEYuIhdensHU3b5qH5ons2quepd6EaRgCHXab6PQoyCgZzdXBwbHkSKAomCIjYAxIglWLA5/THPTiTxAlaLHOBYFIzEJTmKPznItUwAc8zD+AKEgoIZXZpZGVuY2USBgoECIjYAwowCgRtaW50EigKJgiI2AMSIMS8dZ1j8F6JVVv+hB1rHBZC+gIFJxHan2hM8qDC64n/CjIKBnBhcmFtcxIoCiYIiNgDEiB8VIzExUHX+SvHZFz/P9NM9THnw/gTDDLVReuZX8htLgo4CgxkaXN0cmlidXRpb24SKAomCIjYAxIg3u/Nd4L+8LT8OXJCh14o8PHIJ/GLQwsmE7KYIl1GdSYKEgoIdHJhbnNmZXISBgoECIjYAw=="
}
]
},
"height": "60424",
"codespace": ""
}
1 change: 1 addition & 0 deletions relayer/cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ authors = [

[dependencies]
relayer = { path = "../relay" }
relayer-modules = { path = "../../modules" }
tendermint = { git = "https://github.com/informalsystems/tendermint-rs.git" }

anomaly = "0.2.0"
Expand Down
17 changes: 12 additions & 5 deletions relayer/cli/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,13 @@

mod config;
mod light;
mod query;
mod start;
mod version;

use self::{config::ConfigCmd, light::LightCmd, start::StartCmd, version::VersionCmd};
use self::{
config::ConfigCmd, light::LightCmd, query::QueryCmd, start::StartCmd, version::VersionCmd,
};

use crate::config::Config;
use abscissa_core::{Command, Configurable, FrameworkError, Help, Options, Runnable};
Expand All @@ -26,10 +29,6 @@ pub enum CliCmd {
#[options(help = "get usage information")]
Help(Help<Self>),

/// The `version` subcommand
#[options(help = "display version information")]
Version(VersionCmd),

/// The `start` subcommand
#[options(help = "start the relayer")]
Start(StartCmd),
Expand All @@ -38,6 +37,14 @@ pub enum CliCmd {
#[options(help = "manipulate the relayer configuration")]
Config(ConfigCmd),

/// The `version` subcommand
#[options(help = "display version information")]
Version(VersionCmd),

/// The `query` subcommand
#[options(help = "query state from chain")]
Query(QueryCmd),

/// The `light` subcommand
#[options(help = "basic functionality for managing the lite clients")]
Light(LightCmd),
Expand Down
13 changes: 13 additions & 0 deletions relayer/cli/src/commands/query.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//! `query` subcommand

use abscissa_core::{Command, Options, Runnable};

mod query;

/// `query` subcommand
#[derive(Command, Debug, Options, Runnable)]
pub enum QueryCmd {
/// The `query clients` subcommand
#[options(help = "IBC query to a full node")]
Clients(query::QueryClientsCmd),
}
Loading