Skip to content

Commit e8cf761

Browse files
Check query parameters but not against the config (#78)
* Check query parameters but not against the config Fixed parameter verification order to be consistent Simplified the code * Fix error string * Added some tests * Fix clippy and test errors tendermint-rs changed the AbciQuery.value to non-option * add forgotten test fixture * attempt to fix codecov * Minor fix in error msg Co-authored-by: Shivani Joshi <[email protected]>
1 parent 8feb8dc commit e8cf761

File tree

8 files changed

+307
-93
lines changed

8 files changed

+307
-93
lines changed

codecov.yml

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
codecov:
22
require_ci_to_pass: yes
3+
allow_coverage_offsets: true
34

45
ignore:
56

modules/src/ics02_client/query.rs

+12-26
Original file line numberDiff line numberDiff line change
@@ -88,19 +88,12 @@ where
8888
query: QueryClientFullState<CLS>,
8989
response: AbciQuery,
9090
) -> Result<Self, error::Error> {
91-
match (response.value, &response.proof) {
92-
(Some(value), _) => {
93-
let client_state = amino_unmarshal_binary_length_prefixed(&value)?;
94-
95-
Ok(ClientFullStateResponse::new(
96-
query.client_id,
97-
client_state,
98-
response.proof,
99-
response.height.into(),
100-
))
101-
}
102-
(None, _) => Err(error::Kind::Rpc.context("Bad response").into()),
103-
}
91+
Ok(ClientFullStateResponse::new(
92+
query.client_id,
93+
amino_unmarshal_binary_length_prefixed(&response.value)?,
94+
response.proof,
95+
response.height.into(),
96+
))
10497
}
10598
}
10699

@@ -192,18 +185,11 @@ where
192185
query: QueryClientConsensusState<CS>,
193186
response: AbciQuery,
194187
) -> Result<Self, error::Error> {
195-
match (response.value, &response.proof) {
196-
(Some(value), _) => {
197-
let consensus_state = amino_unmarshal_binary_length_prefixed(&value)?;
198-
199-
Ok(ConsensusStateResponse::new(
200-
query.client_id,
201-
consensus_state,
202-
response.proof,
203-
response.height.into(),
204-
))
205-
}
206-
(None, _) => Err(error::Kind::Rpc.context("Bad response").into()),
207-
}
188+
Ok(ConsensusStateResponse::new(
189+
query.client_id,
190+
amino_unmarshal_binary_length_prefixed(&response.value)?,
191+
response.proof,
192+
response.height.into(),
193+
))
208194
}
209195
}

modules/src/ics04_channel/msgs.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ mod tests {
146146
Test {
147147
name: "Bad channel, name too short".to_string(),
148148
params: OpenInitParams {
149-
channel_id: "connone".to_string(),
149+
channel_id: "chshort".to_string(),
150150
..default_params.clone()
151151
},
152152
want_pass: false,

modules/src/ics04_channel/query.rs

+7-14
Original file line numberDiff line numberDiff line change
@@ -79,20 +79,13 @@ impl ChannelResponse {
7979

8080
impl IbcResponse<QueryChannel> for ChannelResponse {
8181
fn from_abci_response(query: QueryChannel, response: AbciQuery) -> Result<Self, error::Error> {
82-
match (response.value, &response.proof) {
83-
(Some(value), _) => {
84-
let channel = amino_unmarshal_binary_length_prefixed(&value)?;
85-
86-
Ok(ChannelResponse::new(
87-
query.port_id,
88-
query.channel_id,
89-
channel,
90-
response.proof,
91-
response.height.into(),
92-
))
93-
}
94-
(None, _) => Err(error::Kind::Rpc.context("Bad response").into()),
95-
}
82+
Ok(ChannelResponse::new(
83+
query.port_id,
84+
query.channel_id,
85+
amino_unmarshal_binary_length_prefixed(&response.value)?,
86+
response.proof,
87+
response.height.into(),
88+
))
9689
}
9790
}
9891

relayer/cli/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,4 @@ version = "0.5.2"
2929

3030
[dev-dependencies]
3131
abscissa_core = { version = "0.5.2", features = ["testing"] }
32-
once_cell = "1.2"
32+
once_cell = "1.2"

relayer/cli/src/commands/query/channel.rs

+147-27
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@ use relayer_modules::ics24_host::identifier::{ChannelId, PortId};
88

99
use crate::commands::utils::block_on;
1010
use relayer::chain::tendermint::TendermintChain;
11+
use relayer_modules::ics24_host::error::ValidationError;
1112
use tendermint::chain::Id as ChainId;
1213

13-
#[derive(Command, Debug, Options)]
14+
#[derive(Clone, Command, Debug, Options)]
1415
pub struct QueryChannelEndsCmd {
1516
#[options(free, help = "identifier of the chain to query")]
1617
chain_id: Option<ChainId>,
@@ -41,32 +42,42 @@ impl QueryChannelEndsCmd {
4142
&self,
4243
config: &Config,
4344
) -> Result<(ChainConfig, QueryChannelOptions), String> {
44-
match (&self.chain_id, &self.port_id, &self.channel_id) {
45-
(Some(chain_id), Some(port_id), Some(channel_id)) => {
46-
let chain_config = config.chains.iter().find(|c| c.id == *chain_id);
47-
match chain_config {
48-
Some(chain_config) => {
49-
let opts = QueryChannelOptions {
50-
port_id: port_id.parse().unwrap(),
51-
channel_id: channel_id.parse().unwrap(),
52-
height: match self.height {
53-
Some(h) => h,
54-
None => 0 as u64,
55-
},
56-
proof: match self.proof {
57-
Some(proof) => proof,
58-
None => true,
59-
},
60-
};
61-
Ok((chain_config.clone(), opts))
62-
}
63-
_ => Err(format!("cannot find chain {} in config", chain_id)),
64-
}
65-
}
66-
(None, _, _) => Err("missing chain identifier".to_string()),
67-
(_, None, _) => Err("missing port identifier".to_string()),
68-
(_, _, None) => Err("missing channel identifier".to_string()),
69-
}
45+
let chain_id = self
46+
.chain_id
47+
.ok_or_else(|| "missing chain identifier".to_string())?;
48+
let chain_config = config
49+
.chains
50+
.iter()
51+
.find(|c| c.id == chain_id)
52+
.ok_or_else(|| "missing chain configuration".to_string())?;
53+
54+
let port_id = self
55+
.port_id
56+
.as_ref()
57+
.ok_or_else(|| "missing port identifier".to_string())?
58+
.parse()
59+
.map_err(|err: ValidationError| err.to_string())?;
60+
61+
let channel_id = self
62+
.channel_id
63+
.as_ref()
64+
.ok_or_else(|| "missing channel identifier".to_string())?
65+
.parse()
66+
.map_err(|err: ValidationError| err.to_string())?;
67+
68+
let opts = QueryChannelOptions {
69+
port_id,
70+
channel_id,
71+
height: match self.height {
72+
Some(h) => h,
73+
None => 0 as u64,
74+
},
75+
proof: match self.proof {
76+
Some(proof) => proof,
77+
None => true,
78+
},
79+
};
80+
Ok((chain_config.clone(), opts))
7081
}
7182
}
7283

@@ -105,3 +116,112 @@ impl Runnable for QueryChannelEndsCmd {
105116
}
106117
}
107118
}
119+
120+
#[cfg(test)]
121+
mod tests {
122+
use crate::commands::query::channel::QueryChannelEndsCmd;
123+
use relayer::config::parse;
124+
125+
#[test]
126+
fn parse_query_ends_parameters() {
127+
let default_params = QueryChannelEndsCmd {
128+
chain_id: Some("ibc0".to_string().parse().unwrap()),
129+
port_id: Some("transfer".to_string().parse().unwrap()),
130+
channel_id: Some("testchannel".to_string().parse().unwrap()),
131+
height: None,
132+
proof: None,
133+
};
134+
135+
struct Test {
136+
name: String,
137+
params: QueryChannelEndsCmd,
138+
want_pass: bool,
139+
}
140+
141+
let tests: Vec<Test> = vec![
142+
Test {
143+
name: "Good parameters".to_string(),
144+
params: default_params.clone(),
145+
want_pass: true,
146+
},
147+
Test {
148+
name: "No chain specified".to_string(),
149+
params: QueryChannelEndsCmd {
150+
chain_id: None,
151+
..default_params.clone()
152+
},
153+
want_pass: false,
154+
},
155+
Test {
156+
name: "Chain not configured".to_string(),
157+
params: QueryChannelEndsCmd {
158+
chain_id: Some("notibc0oribc1".to_string().parse().unwrap()),
159+
..default_params.clone()
160+
},
161+
want_pass: false,
162+
},
163+
Test {
164+
name: "No port id specified".to_string(),
165+
params: QueryChannelEndsCmd {
166+
port_id: None,
167+
..default_params.clone()
168+
},
169+
want_pass: false,
170+
},
171+
Test {
172+
name: "Bad port, non-alpha".to_string(),
173+
params: QueryChannelEndsCmd {
174+
port_id: Some("p34".to_string()),
175+
..default_params.clone()
176+
},
177+
want_pass: false,
178+
},
179+
Test {
180+
name: "No channel id specified".to_string(),
181+
params: QueryChannelEndsCmd {
182+
channel_id: None,
183+
..default_params.clone()
184+
},
185+
want_pass: false,
186+
},
187+
Test {
188+
name: "Bad channel, name too short".to_string(),
189+
params: QueryChannelEndsCmd {
190+
channel_id: Some("chshort".to_string()),
191+
..default_params.clone()
192+
},
193+
want_pass: false,
194+
},
195+
]
196+
.into_iter()
197+
.collect();
198+
199+
let path = concat!(
200+
env!("CARGO_MANIFEST_DIR"),
201+
"/tests/fixtures/two_chains.toml"
202+
);
203+
204+
let config = parse(path).unwrap();
205+
206+
for test in tests {
207+
let res = test.params.validate_options(&config);
208+
209+
match res {
210+
Ok(_res) => {
211+
assert!(
212+
test.want_pass,
213+
"validate_options should have failed for test {}",
214+
test.name
215+
);
216+
}
217+
Err(err) => {
218+
assert!(
219+
!test.want_pass,
220+
"validate_options failed for test {}, \nerr {}",
221+
test.name, err
222+
);
223+
}
224+
}
225+
}
226+
}
227+
}

0 commit comments

Comments
 (0)