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

Allow a conn open ack to succeed in the happy case #700

Merged
merged 9 commits into from
Feb 23, 2021
4 changes: 2 additions & 2 deletions modules/src/ics02_client/client_def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ pub trait ClientDef: Clone {
height: Height,
prefix: &CommitmentPrefix,
proof: &CommitmentProofBytes,
connection_id: &ConnectionId,
connection_id: Option<&ConnectionId>,
expected_connection_end: &ConnectionEnd,
) -> Result<(), Box<dyn std::error::Error>>;

Expand Down Expand Up @@ -472,7 +472,7 @@ impl ClientDef for AnyClient {
height: Height,
prefix: &CommitmentPrefix,
proof: &CommitmentProofBytes,
connection_id: &ConnectionId,
connection_id: Option<&ConnectionId>,
expected_connection_end: &ConnectionEnd,
) -> Result<(), Box<dyn std::error::Error>> {
match self {
Expand Down
36 changes: 13 additions & 23 deletions modules/src/ics03_connection/handler/conn_open_ack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,19 @@ pub(crate) fn process(
|| old_conn_end.state_matches(&State::TryOpen)
&& old_conn_end.versions().get(0).eq(&Some(msg.version()));

// Check that if the msg's counterparty connection id is not empty then it matches
// the old connection's counterparty.
let counterparty_matches = msg.counterparty_connection_id().is_none()
|| old_conn_end.counterparty().connection_id() == msg.counterparty_connection_id();
// Check that if we have a counterparty connection id, then it
// matches the one in the message
let counterparty_matches = if let Some(counterparty_connection_id) =
old_conn_end.counterparty().connection_id()
{
// it's okay to unwrap as `msg.counterparty_connection_id`
// should always be set
// TODO: `msg.counterparty_connection_id` should simply be a
// `ConnectionId`, not an `Option<ConnectionId>`
msg.counterparty_connection_id.as_ref().unwrap() == counterparty_connection_id
} else {
true
};

if state_is_consistent && counterparty_matches {
Ok(old_conn_end)
Expand Down Expand Up @@ -168,16 +177,6 @@ mod tests {
CommitmentPrefix::from(vec![]), // incorrect field
));

// A connection end with correct state & prefix, but incorrect counterparty; exercises
// unsuccessful processing path.
let mut conn_end_cparty = conn_end_open.clone();
conn_end_cparty.set_state(State::Init);
conn_end_cparty.set_counterparty(Counterparty::new(
client_id.clone(),
None, // incorrect field
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This test has been removed as my understanding is that msg.counterparty_connection_id should always be a Some (which hints that it should not be an Option).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Now this field is no longer an Option.

CommitmentPrefix::from(b"ibc".to_vec()),
));

let tests: Vec<Test> = vec![
Test {
name: "Successful processing of an Ack message".to_string(),
Expand Down Expand Up @@ -216,15 +215,6 @@ mod tests {
want_pass: false,
error_kind: Some(Kind::ConsensusStateVerificationFailure(proof_height))
},
Test {
name: "Processing fails due to mismatching counterparty conn id".to_string(),
ctx: default_context
.with_client(&client_id, proof_height)
.with_connection(conn_id.clone(), conn_end_cparty),
msg: ConnectionMsg::ConnectionOpenAck(Box::new(msg_ack)),
want_pass: false,
error_kind: Some(Kind::ConnectionMismatch(conn_id))
},
/*
Test {
name: "Processing fails due to MissingLocalConsensusState".to_string(),
Expand Down
2 changes: 1 addition & 1 deletion modules/src/ics03_connection/handler/verify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ pub fn verify_connection_proof(
proof_height,
connection_end.counterparty().prefix(),
proof,
&connection_end.counterparty().connection_id().unwrap(),
connection_end.counterparty().connection_id(),
Copy link
Contributor Author

Choose a reason for hiding this comment

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

If the connection is in the Init state, connection_end.counterparty().connection_id() is a None, and thus it's not okay to unwrap.

expected_conn,
)
.map_err(|_| Kind::InvalidProof)?)
Expand Down
2 changes: 1 addition & 1 deletion modules/src/ics07_tendermint/client_def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ impl ClientDef for TendermintClient {
_height: Height,
_prefix: &CommitmentPrefix,
_proof: &CommitmentProofBytes,
_connection_id: &ConnectionId,
_connection_id: Option<&ConnectionId>,
_expected_connection_end: &ConnectionEnd,
) -> Result<(), Box<dyn std::error::Error>> {
todo!()
Expand Down
2 changes: 1 addition & 1 deletion modules/src/mock/client_def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ impl ClientDef for MockClient {
_height: Height,
_prefix: &CommitmentPrefix,
_proof: &CommitmentProofBytes,
_connection_id: &ConnectionId,
_connection_id: Option<&ConnectionId>,
_expected_connection_end: &ConnectionEnd,
) -> Result<(), Box<dyn std::error::Error>> {
Ok(())
Expand Down