ibc_core_host/context.rs
1use core::time::Duration;
2
3use ibc_core_channel_types::channel::ChannelEnd;
4use ibc_core_channel_types::commitment::{AcknowledgementCommitment, PacketCommitment};
5use ibc_core_channel_types::packet::Receipt;
6use ibc_core_client_context::prelude::*;
7use ibc_core_client_types::Height;
8use ibc_core_commitment_types::commitment::CommitmentPrefix;
9use ibc_core_connection_types::version::{pick_version, Version as ConnectionVersion};
10use ibc_core_connection_types::ConnectionEnd;
11use ibc_core_handler_types::events::IbcEvent;
12use ibc_core_host_types::error::HostError;
13use ibc_core_host_types::identifiers::{ConnectionId, Sequence};
14use ibc_core_host_types::path::{
15 AckPath, ChannelEndPath, ClientConnectionPath, CommitmentPath, ConnectionPath, ReceiptPath,
16 SeqAckPath, SeqRecvPath, SeqSendPath,
17};
18use ibc_primitives::prelude::*;
19use ibc_primitives::{Signer, Timestamp};
20
21use crate::utils::calculate_block_delay;
22
23/// Context to be implemented by the host that provides all "read-only" methods.
24///
25/// Trait used for the top-level `validate` entrypoint in the `ibc-core` crate.
26pub trait ValidationContext {
27 type V: ClientValidationContext;
28 /// The client state type for the host chain.
29 type HostClientState: ClientStateValidation<Self::V>;
30 /// The consensus state type for the host chain.
31 type HostConsensusState: ConsensusState;
32
33 /// Retrieve the context that implements all clients' `ValidationContext`.
34 fn get_client_validation_context(&self) -> &Self::V;
35
36 /// Returns the current height of the local chain.
37 fn host_height(&self) -> Result<Height, HostError>;
38
39 /// Returns the current timestamp of the local chain.
40 fn host_timestamp(&self) -> Result<Timestamp, HostError>;
41
42 /// Returns the `ConsensusState` of the host (local) chain at a specific height.
43 fn host_consensus_state(&self, height: &Height) -> Result<Self::HostConsensusState, HostError>;
44
45 /// Returns a natural number, counting how many clients have been created
46 /// thus far. The value of this counter should increase only via method
47 /// `ExecutionContext::increase_client_counter`.
48 fn client_counter(&self) -> Result<u64, HostError>;
49
50 /// Returns the ConnectionEnd for the given identifier `conn_id`.
51 fn connection_end(&self, conn_id: &ConnectionId) -> Result<ConnectionEnd, HostError>;
52
53 /// Validates the `ClientState` of the host chain stored on the counterparty
54 /// chain against the host's internal state.
55 ///
56 /// For more information on the specific requirements for validating the
57 /// client state of a host chain, please refer to the [ICS24 host
58 /// requirements](https://github.com/cosmos/ibc/tree/main/spec/core/ics-024-host-requirements#client-state-validation)
59 ///
60 /// Additionally, implementations specific to individual chains can be found
61 /// in the `ibc-core/ics24-host` module.
62 fn validate_self_client(
63 &self,
64 client_state_of_host_on_counterparty: Self::HostClientState,
65 ) -> Result<(), HostError>;
66
67 /// Returns the prefix that the local chain uses in the KV store.
68 fn commitment_prefix(&self) -> CommitmentPrefix;
69
70 /// Returns a counter on how many connections have been created thus far.
71 fn connection_counter(&self) -> Result<u64, HostError>;
72
73 /// Function required by ICS-03. Returns the list of all possible versions that the connection
74 /// handshake protocol supports.
75 fn get_compatible_versions(&self) -> Vec<ConnectionVersion> {
76 ConnectionVersion::compatibles()
77 }
78
79 /// Function required by ICS-03. Returns one version out of the supplied list of versions, which the
80 /// connection handshake protocol prefers.
81 fn pick_version(
82 &self,
83 counterparty_candidate_versions: &[ConnectionVersion],
84 ) -> Result<ConnectionVersion, HostError> {
85 pick_version(
86 &self.get_compatible_versions(),
87 counterparty_candidate_versions,
88 )
89 .map_err(HostError::missing_state)
90 }
91
92 /// Returns the `ChannelEnd` for the given `port_id` and `chan_id`.
93 fn channel_end(&self, channel_end_path: &ChannelEndPath) -> Result<ChannelEnd, HostError>;
94
95 /// Returns the sequence number for the next packet to be sent for the given store path
96 fn get_next_sequence_send(&self, seq_send_path: &SeqSendPath) -> Result<Sequence, HostError>;
97
98 /// Returns the sequence number for the next packet to be received for the given store path
99 fn get_next_sequence_recv(&self, seq_recv_path: &SeqRecvPath) -> Result<Sequence, HostError>;
100
101 /// Returns the sequence number for the next packet to be acknowledged for the given store path
102 fn get_next_sequence_ack(&self, seq_ack_path: &SeqAckPath) -> Result<Sequence, HostError>;
103
104 /// Returns the packet commitment for the given store path
105 fn get_packet_commitment(
106 &self,
107 commitment_path: &CommitmentPath,
108 ) -> Result<PacketCommitment, HostError>;
109
110 /// Returns the packet receipt for the given store path. This receipt is
111 /// used to acknowledge the successful processing of a received packet, and
112 /// must not be pruned.
113 ///
114 /// If the receipt is present in the host's state, return `Receipt::Ok`,
115 /// indicating the packet has already been processed. If the receipt is
116 /// absent, return `Receipt::None`, indicating the packet has not been
117 /// received.
118 fn get_packet_receipt(&self, receipt_path: &ReceiptPath) -> Result<Receipt, HostError>;
119
120 /// Returns the packet acknowledgement for the given store path
121 fn get_packet_acknowledgement(
122 &self,
123 ack_path: &AckPath,
124 ) -> Result<AcknowledgementCommitment, HostError>;
125
126 /// Returns a counter on the number of channel ids have been created thus far.
127 /// The value of this counter should increase only via method
128 /// `ExecutionContext::increase_channel_counter`.
129 fn channel_counter(&self) -> Result<u64, HostError>;
130
131 /// Returns the maximum expected time per block
132 fn max_expected_time_per_block(&self) -> Duration;
133
134 /// Calculates the block delay period using the connection's delay period and the maximum
135 /// expected time per block.
136 fn block_delay(&self, delay_period_time: &Duration) -> u64 {
137 calculate_block_delay(delay_period_time, &self.max_expected_time_per_block())
138 }
139
140 /// Validates the `signer` field of IBC messages, which represents the address
141 /// of the user/relayer that signed the given message.
142 fn validate_message_signer(&self, signer: &Signer) -> Result<(), HostError>;
143}
144
145/// Context to be implemented by the host that provides all "write-only" methods.
146///
147/// Trait used for the top-level `execute` and `dispatch` entrypoints in the `ibc-core` crate.
148pub trait ExecutionContext: ValidationContext {
149 type E: ClientExecutionContext;
150
151 /// Retrieve the context that implements all clients' `ExecutionContext`.
152 fn get_client_execution_context(&mut self) -> &mut Self::E;
153
154 /// Called upon client creation.
155 /// Increases the counter, that keeps track of how many clients have been created.
156 fn increase_client_counter(&mut self) -> Result<(), HostError>;
157
158 /// Stores the given connection_end at path
159 fn store_connection(
160 &mut self,
161 connection_path: &ConnectionPath,
162 connection_end: ConnectionEnd,
163 ) -> Result<(), HostError>;
164
165 /// Stores the given connection_id at a path associated with the client_id.
166 fn store_connection_to_client(
167 &mut self,
168 client_connection_path: &ClientConnectionPath,
169 conn_id: ConnectionId,
170 ) -> Result<(), HostError>;
171
172 /// Called upon connection identifier creation (Init or Try process).
173 /// Increases the counter which keeps track of how many connections have been created.
174 fn increase_connection_counter(&mut self) -> Result<(), HostError>;
175
176 /// Stores the given packet commitment at the given store path
177 fn store_packet_commitment(
178 &mut self,
179 commitment_path: &CommitmentPath,
180 commitment: PacketCommitment,
181 ) -> Result<(), HostError>;
182
183 /// Deletes the packet commitment at the given store path
184 fn delete_packet_commitment(
185 &mut self,
186 commitment_path: &CommitmentPath,
187 ) -> Result<(), HostError>;
188
189 /// Stores the given packet receipt at the given store path
190 fn store_packet_receipt(
191 &mut self,
192 receipt_path: &ReceiptPath,
193 receipt: Receipt,
194 ) -> Result<(), HostError>;
195
196 /// Stores the given packet acknowledgement at the given store path
197 fn store_packet_acknowledgement(
198 &mut self,
199 ack_path: &AckPath,
200 ack_commitment: AcknowledgementCommitment,
201 ) -> Result<(), HostError>;
202
203 /// Deletes the packet acknowledgement at the given store path
204 fn delete_packet_acknowledgement(&mut self, ack_path: &AckPath) -> Result<(), HostError>;
205
206 /// Stores the given channel_end at a path associated with the port_id and channel_id.
207 fn store_channel(
208 &mut self,
209 channel_end_path: &ChannelEndPath,
210 channel_end: ChannelEnd,
211 ) -> Result<(), HostError>;
212
213 /// Stores the given `nextSequenceSend` number at the given store path
214 fn store_next_sequence_send(
215 &mut self,
216 seq_send_path: &SeqSendPath,
217 seq: Sequence,
218 ) -> Result<(), HostError>;
219
220 /// Stores the given `nextSequenceRecv` number at the given store path
221 fn store_next_sequence_recv(
222 &mut self,
223 seq_recv_path: &SeqRecvPath,
224 seq: Sequence,
225 ) -> Result<(), HostError>;
226
227 /// Stores the given `nextSequenceAck` number at the given store path
228 fn store_next_sequence_ack(
229 &mut self,
230 seq_ack_path: &SeqAckPath,
231 seq: Sequence,
232 ) -> Result<(), HostError>;
233
234 /// Called upon channel identifier creation (Init or Try message processing).
235 /// Increases the counter, that keeps track of how many channels have been created.
236 fn increase_channel_counter(&mut self) -> Result<(), HostError>;
237
238 /// Emit the given IBC event
239 fn emit_ibc_event(&mut self, event: IbcEvent) -> Result<(), HostError>;
240
241 /// Log the given message.
242 fn log_message(&mut self, message: String) -> Result<(), HostError>;
243}
244
245/// Convenient type alias for `ClientStateRef`, providing access to client
246/// validation methods within the context.
247pub type ClientStateRef<Ctx> =
248 <<Ctx as ValidationContext>::V as ClientValidationContext>::ClientStateRef;
249
250/// Convenient type alias for `ClientStateMut`, providing access to client
251/// execution methods within the context.
252pub type ClientStateMut<Ctx> =
253 <<Ctx as ExecutionContext>::E as ClientExecutionContext>::ClientStateMut;
254
255/// Convenient type alias for `ConsensusStateRef`, providing access to client
256/// validation methods within the context.
257pub type ConsensusStateRef<Ctx> =
258 <<Ctx as ValidationContext>::V as ClientValidationContext>::ConsensusStateRef;