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;