1515// along with this program. If not, see <https://www.gnu.org/licenses/>.
1616
1717use super :: path as connection_path;
18- use super :: types:: { CommitmentPrefix , Identifier } ;
18+ use super :: types:: { CommitmentPrefix , CommitmentProof , Identifier } ;
1919use crate :: ibc;
2020use crate :: ibc:: connection_03:: client_connections_path;
2121use crate :: ibc:: connection_03:: types:: { ConnectionEnd , ConnectionIdentifiersInClient , ConnectionState } ;
@@ -24,6 +24,11 @@ use rlp::{Encodable, Rlp};
2424#[ derive( Default ) ]
2525pub struct Manager { }
2626
27+ // FIXME: this will be changed after implementing Vector commitment
28+ fn get_commiment_prefix ( ) -> String {
29+ "" . to_owned ( )
30+ }
31+
2732impl 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 ,
0 commit comments