Skip to main content

pallet_ismp/
utils.rs

1// Copyright (c) 2025 Polytope Labs.
2// SPDX-License-Identifier: Apache-2.0
3
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// 	http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16//! Pallet utilities
17use polkadot_sdk::*;
18
19use alloc::collections::BTreeMap;
20
21use codec::{Decode, DecodeWithMemTracking, Encode};
22use frame_support::PalletId;
23use ismp::{
24	consensus::{ConsensusClient, ConsensusStateId},
25	host::StateMachine,
26};
27use sp_core::{
28	crypto::{AccountId32, ByteArray},
29	H160, H256,
30};
31use sp_std::prelude::*;
32
33/// Params to update the unbonding period for a consensus state
34#[derive(
35	Debug, Clone, Encode, Decode, DecodeWithMemTracking, scale_info::TypeInfo, PartialEq, Eq,
36)]
37pub struct UpdateConsensusState {
38	/// Consensus state identifier
39	pub consensus_state_id: ConsensusStateId,
40	/// Unbonding duration
41	pub unbonding_period: Option<u64>,
42	/// Challenge period duration for different state machines
43	pub challenge_periods: BTreeMap<StateMachine, u64>,
44}
45
46/// Holds a commitment to either a request or response
47#[derive(
48	Debug, Clone, Encode, Decode, DecodeWithMemTracking, scale_info::TypeInfo, PartialEq, Eq,
49)]
50pub enum MessageCommitment {
51	/// A request message
52	Request(H256),
53	/// A response message
54	Response(H256),
55}
56
57/// Params to add more funds for request delivery
58#[derive(
59	Debug, Clone, Encode, Decode, DecodeWithMemTracking, scale_info::TypeInfo, PartialEq, Eq,
60)]
61pub struct FundMessageParams<Balance> {
62	/// Message commitment
63	pub commitment: MessageCommitment,
64	/// Amount to fund message by
65	pub amount: Balance,
66}
67
68/// Receipt for a Response
69#[derive(Debug, Clone, Encode, Decode, scale_info::TypeInfo, PartialEq, Eq)]
70pub struct ResponseReceipt {
71	/// Hash of the response object
72	pub response: H256,
73	/// Address of the relayer
74	pub relayer: Vec<u8>,
75}
76
77/// A  convenience trait that returns a list of all configured consensus clients
78/// This trait should be implemented in the runtime
79pub trait ConsensusClientProvider {
80	/// Returns a list of all configured consensus clients
81	fn consensus_clients() -> Vec<Box<dyn ConsensusClient>>;
82}
83
84fortuples::fortuples! {
85	#[tuples::max_size(30)]
86	impl ConsensusClientProvider for #Tuple
87	where
88		#(#Member: ConsensusClient + Default + 'static),*
89	{
90
91		fn consensus_clients() -> Vec<Box<dyn ConsensusClient>> {
92			vec![
93				#( Box::new(#Member::default()) as Box<dyn ConsensusClient> ),*
94			]
95		}
96	}
97}
98
99/// Module identification types supported by ismp
100#[derive(PartialEq, Eq, scale_info::TypeInfo)]
101pub enum ModuleId {
102	/// Unique Pallet identification in runtime
103	Pallet(PalletId),
104	/// Contract account id
105	Contract(AccountId32),
106	/// Evm contract
107	Evm(H160),
108}
109
110impl ModuleId {
111	/// Convert module id to raw bytes
112	pub fn to_bytes(&self) -> Vec<u8> {
113		match self {
114			ModuleId::Pallet(pallet_id) => pallet_id.0.to_vec(),
115			ModuleId::Contract(account_id) => account_id.as_slice().to_vec(),
116			ModuleId::Evm(account_id) => account_id.0.to_vec(),
117		}
118	}
119
120	/// Derive module id from raw bytes
121	pub fn from_bytes(bytes: &[u8]) -> Result<Self, &'static str> {
122		if bytes.len() == 8 {
123			let mut inner = [0u8; 8];
124			inner.copy_from_slice(bytes);
125			Ok(Self::Pallet(PalletId(inner)))
126		} else if bytes.len() == 32 {
127			Ok(Self::Contract(AccountId32::from_slice(bytes).expect("Infallible")))
128		} else if bytes.len() == 20 {
129			Ok(Self::Evm(H160::from_slice(bytes)))
130		} else {
131			Err("Unknown Module ID format")
132		}
133	}
134}
135
136/// The `ConsensusEngineId` of ISMP `ConsensusDigest` in the parachain header.
137pub const ISMP_ID: sp_runtime::ConsensusEngineId = *b"ISMP";
138
139/// Consensus log digest for pallet ismp
140#[derive(Encode, Decode, Clone, scale_info::TypeInfo, Default)]
141pub struct ConsensusDigest {
142	/// Mmr root hash
143	pub mmr_root: H256,
144	/// Child trie root hash
145	pub child_trie_root: H256,
146}
147
148/// The `ConsensusEngineId` of Ismp `TimestampDigest` in the parachain header.
149pub const ISMP_TIMESTAMP_ID: sp_runtime::ConsensusEngineId = *b"ISTM";
150
151/// Timestamp log digest for pallet ismp
152#[derive(Encode, Decode, Clone, scale_info::TypeInfo, Default)]
153pub struct TimestampDigest {
154	/// Timestamp value in seconds
155	pub timestamp: u64,
156}