Skip to content

Commit db33a78

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 db33a78

File tree

4 files changed

+191
-1
lines changed

4 files changed

+191
-1
lines changed

core/src/ibc/connection_03/manager.rs

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

core/src/ibc/transaction_handler/datagrams.rs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ enum DatagramTag {
2222
CreateClient = 1,
2323
UpdateClient = 2,
2424
ConnOpenInit = 3,
25+
ConnOpenTry = 4,
2526
}
2627

2728
impl Encodable for DatagramTag {
@@ -37,6 +38,7 @@ impl Decodable for DatagramTag {
3738
1 => Ok(DatagramTag::CreateClient),
3839
2 => Ok(DatagramTag::UpdateClient),
3940
3 => Ok(DatagramTag::ConnOpenInit),
41+
4 => Ok(DatagramTag::ConnOpenTry),
4042
_ => Err(DecoderError::Custom("Unexpected DatagramTag Value")),
4143
}
4244
}
@@ -60,6 +62,17 @@ pub enum Datagram {
6062
client_identifier: String,
6163
counterparty_client_identifier: String,
6264
},
65+
ConnOpenTry {
66+
desired_identifier: String,
67+
counterparty_connection_identifier: String,
68+
counterparty_prefix: String,
69+
counterparty_client_identifier: String,
70+
client_identifier: String,
71+
proof_init: String,
72+
proof_consensus: String,
73+
proof_height: u64,
74+
consensus_height: u64,
75+
},
6376
}
6477

6578
impl Encodable for Datagram {
@@ -93,6 +106,29 @@ impl Encodable for Datagram {
93106
.append(client_identifier)
94107
.append(counterparty_client_identifier);
95108
}
109+
Datagram::ConnOpenTry {
110+
desired_identifier,
111+
counterparty_connection_identifier,
112+
counterparty_prefix,
113+
counterparty_client_identifier,
114+
client_identifier,
115+
proof_init,
116+
proof_consensus,
117+
proof_height,
118+
consensus_height,
119+
} => {
120+
s.begin_list(10);
121+
s.append(&DatagramTag::ConnOpenTry)
122+
.append(desired_identifier)
123+
.append(counterparty_connection_identifier)
124+
.append(counterparty_prefix)
125+
.append(counterparty_client_identifier)
126+
.append(client_identifier)
127+
.append(proof_init)
128+
.append(proof_consensus)
129+
.append(proof_height)
130+
.append(consensus_height);
131+
}
96132
};
97133
}
98134
}
@@ -144,6 +180,26 @@ impl Decodable for Datagram {
144180
counterparty_client_identifier: rlp.val_at(5)?,
145181
})
146182
}
183+
DatagramTag::ConnOpenTry => {
184+
let item_count = rlp.item_count()?;
185+
if item_count != 10 {
186+
return Err(DecoderError::RlpInvalidLength {
187+
expected: 10,
188+
got: item_count,
189+
})
190+
}
191+
Ok(Datagram::ConnOpenTry {
192+
desired_identifier: rlp.val_at(1)?,
193+
counterparty_connection_identifier: rlp.val_at(2)?,
194+
counterparty_prefix: rlp.val_at(3)?,
195+
counterparty_client_identifier: rlp.val_at(4)?,
196+
client_identifier: rlp.val_at(5)?,
197+
proof_init: rlp.val_at(6)?,
198+
proof_consensus: rlp.val_at(7)?,
199+
proof_height: rlp.val_at(8)?,
200+
consensus_height: rlp.val_at(9)?,
201+
})
202+
}
147203
}
148204
}
149205
}

core/src/ibc/transaction_handler/mod.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,34 @@ pub fn execute(
6565
)
6666
.map_err(|err| RuntimeError::IBC(format!("ConnOpenInit: {}", err)).into())
6767
}
68+
Datagram::ConnOpenTry {
69+
desired_identifier,
70+
counterparty_connection_identifier,
71+
counterparty_prefix,
72+
counterparty_client_identifier,
73+
client_identifier,
74+
proof_init,
75+
proof_consensus,
76+
proof_height,
77+
consensus_height,
78+
} => {
79+
let mut context = ibc_context::TopLevelContext::new(state, current_block_number);
80+
let connection_manager = ibc_connection::Manager::new();
81+
connection_manager
82+
.handle_open_try(
83+
&mut context,
84+
desired_identifier,
85+
counterparty_connection_identifier,
86+
counterparty_prefix,
87+
counterparty_client_identifier,
88+
client_identifier,
89+
proof_init,
90+
proof_consensus,
91+
proof_height,
92+
consensus_height,
93+
)
94+
.map_err(|err| RuntimeError::IBC(format!("ConnOpenTry: {}", err)).into())
95+
}
6896
}
6997
}
7098

0 commit comments

Comments
 (0)