Skip to content

Commit 99b0513

Browse files
committed
Implement ICS connection's open_try datagram
I omit vector commitment and light client part. I will fill the part after we merge them in the PoC branch.
1 parent 7c93a9b commit 99b0513

File tree

2 files changed

+108
-1
lines changed

2 files changed

+108
-1
lines changed

core/src/ibc/connection_03/manager.rs

Lines changed: 106 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
// along with this program. If not, see <https://www.gnu.org/licenses/>.
1616

1717
use super::path as connection_path;
18-
use super::types::{CommitmentPrefix, Identifier};
18+
use super::types::{CommitmentPrefix, CommitmentProof, Identifier};
1919
use crate::ibc;
2020
use crate::ibc::connection_03::client_connections_path;
2121
use crate::ibc::connection_03::types::{ConnectionEnd, ConnectionIdentifiersInClient, ConnectionState};
@@ -24,6 +24,11 @@ use rlp::{Encodable, Rlp};
2424
#[derive(Default)]
2525
pub struct Manager {}
2626

27+
// FIXME: this will be changed after implementing Vector commitment
28+
fn get_commiment_prefix() -> String {
29+
"".to_owned()
30+
}
31+
2732
impl Manager {
2833
pub fn new() -> Self {
2934
Manager {}
@@ -55,6 +60,106 @@ impl Manager {
5560
Ok(())
5661
}
5762

63+
// We all following ICS spec.
64+
#[allow(clippy::too_many_arguments)]
65+
pub fn handle_open_try(
66+
&self,
67+
ctx: &mut dyn ibc::Context,
68+
desired_identifier: Identifier,
69+
counterparty_connection_identifier: Identifier,
70+
counterparty_prefix: CommitmentPrefix,
71+
counterparty_client_identifier: Identifier,
72+
client_identifier: Identifier,
73+
counterparty_versions: Vec<String>,
74+
proof_init: CommitmentProof,
75+
proof_consensus: CommitmentProof,
76+
proof_height: u64,
77+
consensus_height: u64,
78+
) -> Result<(), String> {
79+
let current_height = ctx.get_current_height();
80+
if consensus_height > current_height {
81+
return Err(format!(
82+
"Consensus height {} is greater than current height {}",
83+
consensus_height, current_height
84+
))
85+
}
86+
let expected = ConnectionEnd {
87+
state: ConnectionState::INIT,
88+
counterparty_connection_identifier: desired_identifier.clone(),
89+
counterparty_prefix: get_commiment_prefix(),
90+
client_identifier: counterparty_client_identifier.clone(),
91+
counterparty_client_identifier: client_identifier.clone(),
92+
};
93+
94+
let connection = ConnectionEnd {
95+
state: ConnectionState::TRYOPEN,
96+
counterparty_connection_identifier: counterparty_client_identifier.clone(),
97+
counterparty_prefix: counterparty_prefix.clone(),
98+
client_identifier: client_identifier.clone(),
99+
counterparty_client_identifier: counterparty_client_identifier.clone(),
100+
};
101+
102+
self.verify_connection_state(ctx, &connection, proof_height, proof_init, desired_identifier.clone(), &expected);
103+
104+
if let Some(previous_connection_end) = self.query(ctx, &desired_identifier) {
105+
let expected_init = ConnectionEnd {
106+
state: ConnectionState::INIT,
107+
counterparty_connection_identifier,
108+
counterparty_prefix,
109+
client_identifier,
110+
counterparty_client_identifier,
111+
};
112+
if previous_connection_end != expected_init {
113+
return Err(format!(
114+
"Invalid previous connection status: previous: {:?}, expected: {:?}",
115+
previous_connection_end, expected_init
116+
))
117+
}
118+
}
119+
120+
let kv_store = ctx.get_kv_store();
121+
kv_store.set(&connection_path(&desired_identifier), &connection.rlp_bytes());
122+
Ok(())
123+
}
124+
125+
fn query(&self, ctx: &mut dyn ibc::Context, identifier: &str) -> Option<ConnectionEnd> {
126+
let kv_store = ctx.get_kv_store();
127+
128+
let path = connection_path(&identifier);
129+
if kv_store.has(&path) {
130+
let raw = kv_store.get(&path);
131+
let connection_end = rlp::decode(&raw).expect("Only the connection code can save the code");
132+
return Some(connection_end)
133+
}
134+
135+
None
136+
}
137+
138+
fn verify_connection_state(
139+
&self,
140+
ctx: &mut dyn ibc::Context,
141+
connection: &ConnectionEnd,
142+
proof_height: u64,
143+
proof: CommitmentProof,
144+
connection_identifier: Identifier,
145+
connection_end: &ConnectionEnd,
146+
) -> bool {
147+
// check values in the connection_end
148+
let path = format!("connections/{}", connection_identifier);
149+
self.client_verify_membership(proof_height, proof, path, &rlp::encode(connection_end))
150+
}
151+
152+
fn client_verify_membership(
153+
&self,
154+
_height: u64,
155+
_commitment_proof: CommitmentProof,
156+
_path: String,
157+
_value: &[u8],
158+
) -> bool {
159+
// FIXME
160+
true
161+
}
162+
58163
fn add_connection_to_client(
59164
&self,
60165
ctx: &mut dyn ibc::Context,

core/src/ibc/connection_03/types.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ impl rlp::Decodable for ConnectionState {
4545

4646
// FIXME: current commitment_23::Prefix is too generic.
4747
pub type CommitmentPrefix = String;
48+
// FIXME: This type will be replaced after commitment code changed.
49+
pub type CommitmentProof = String;
4850
pub type Identifier = String;
4951

5052
#[derive(RlpEncodable, RlpDecodable, PartialEq, Debug)]

0 commit comments

Comments
 (0)