ibc_core_connection/handler/
conn_open_init.rs1use ibc_core_client::context::prelude::*;
3use ibc_core_connection_types::error::ConnectionError;
4use ibc_core_connection_types::events::OpenInit;
5use ibc_core_connection_types::msgs::MsgConnectionOpenInit;
6use ibc_core_connection_types::{ConnectionEnd, Counterparty, State};
7use ibc_core_handler_types::events::{IbcEvent, MessageEvent};
8use ibc_core_host::types::identifiers::ConnectionId;
9use ibc_core_host::types::path::{ClientConnectionPath, ConnectionPath};
10use ibc_core_host::{ExecutionContext, ValidationContext};
11use ibc_primitives::prelude::*;
12
13pub fn validate<Ctx>(ctx_a: &Ctx, msg: MsgConnectionOpenInit) -> Result<(), ConnectionError>
14where
15 Ctx: ValidationContext,
16{
17 ctx_a.validate_message_signer(&msg.signer)?;
18
19 let client_val_ctx_a = ctx_a.get_client_validation_context();
20
21 let client_state_of_b_on_a = client_val_ctx_a.client_state(&msg.client_id_on_a)?;
23
24 client_state_of_b_on_a
25 .status(client_val_ctx_a, &msg.client_id_on_a)?
26 .verify_is_active()?;
27
28 if let Some(version) = msg.version {
29 version.verify_is_supported(&ctx_a.get_compatible_versions())?;
30 }
31
32 Ok(())
33}
34
35pub fn execute<Ctx>(ctx_a: &mut Ctx, msg: MsgConnectionOpenInit) -> Result<(), ConnectionError>
36where
37 Ctx: ExecutionContext,
38{
39 let versions = if let Some(version) = msg.version {
40 version.verify_is_supported(&ctx_a.get_compatible_versions())?;
41 vec![version]
42 } else {
43 ctx_a.get_compatible_versions()
44 };
45
46 let conn_end_on_a = ConnectionEnd::new(
47 State::Init,
48 msg.client_id_on_a.clone(),
49 Counterparty::new(
50 msg.counterparty.client_id().clone(),
51 None,
52 msg.counterparty.prefix().clone(),
53 ),
54 versions,
55 msg.delay_period,
56 )?;
57
58 let conn_id_on_a = ConnectionId::new(ctx_a.connection_counter()?);
60
61 ctx_a.log_message(format!(
62 "success: conn_open_init: generated new connection identifier: {conn_id_on_a}"
63 ))?;
64
65 {
66 let client_id_on_b = msg.counterparty.client_id().clone();
67
68 let event = IbcEvent::OpenInitConnection(OpenInit::new(
69 conn_id_on_a.clone(),
70 msg.client_id_on_a.clone(),
71 client_id_on_b,
72 ));
73 ctx_a.emit_ibc_event(IbcEvent::Message(MessageEvent::Connection))?;
74 ctx_a.emit_ibc_event(event)?;
75 }
76
77 ctx_a.increase_connection_counter()?;
78 ctx_a.store_connection_to_client(
79 &ClientConnectionPath::new(msg.client_id_on_a),
80 conn_id_on_a.clone(),
81 )?;
82 ctx_a.store_connection(&ConnectionPath::new(&conn_id_on_a), conn_end_on_a)?;
83
84 Ok(())
85}