#substrate #interop #ismp #request-response #polkadot-sdk

no-std 托盘-Icmp

Interoperable State Machine Protocol 的 substrate 运行时实现

3 个稳定版本

1.6.2 2024 年 5 月 10 日
1.6.1 2024 年 5 月 6 日
1.6.0 2024 年 5 月 2 日

#1 in #polkadot-sdk

Download history 116/week @ 2024-04-27 326/week @ 2024-05-04 64/week @ 2024-05-11 41/week @ 2024-05-18 17/week @ 2024-05-25 2/week @ 2024-06-01 6/week @ 2024-06-08 11/week @ 2024-06-15

每月 127 次下载
用于 6 crate (5 个直接)

Apache-2.0

200KB
3.5K SLoC

托盘 ISMP

基于 substrate 的链的可互操作状态机协议实现。此托盘提供以下功能:

  1. 通过使用证明共识的“状态承诺”来跟踪远程状态机(区块链)的最终状态。
  2. 通过使用通过已知、先前最终状态承诺验证的状态证明来执行来自连接链的 ISMP 兼容消息。
  3. 将 ISMP 请求和响应调度到连接链。

概述

ISMP 托盘提供以下调用:

  • 创建具有相应解绑、挑战期间和任何初始状态机承诺的共识客户端。
  • 更新共识客户端元数据
  • 执行 ISMP 兼容消息
  • 为飞行中的消息(请求或响应)提供资金

要在您的运行时中使用它,您需要实现 ismp pallet_ismp::Config。支持的可调度函数在 pallet_ismp::Call 枚举中进行了文档说明。

术语

  • ISMP: 可互操作状态机协议,是一个安全、跨链互操作框架。提供消息和状态读取功能。
  • 状态承诺:这指的是整个区块链状态的加密承诺,也称为状态根。
  • 状态机:这指的是区块链本身,我们将区块链标识为状态机。
  • 共识状态:这是共识客户端验证证明所需的最小数据,这些证明证明了新最终状态的有效性。
  • 共识客户端:这是一个验证特定共识机制共识证明的算法。
  • 解绑期间:指的是验证者从连接链中解除质押其资金所需的时间。
  • 挑战期:一个可配置的值,用于等待状态承诺被挑战的时间,在此之后才能用于验证传入的请求/响应。

可调度函数

  • handle - 处理传入的ISMP消息。
  • handle_unsigned 用于处理传入消息的无符号版本,通过 feature = ["unsigned"]
  • create_consensus_client - 处理特定共识客户端的各种属性创建。只能由 AdminOrigin 调用。
  • update_consensus_state - 更新存储中的共识客户端属性。只能由 AdminOrigin 调用。
  • fund_message - 在初始提供的代理费用因目标链上的交易费用激增而不足的情况下。允许用户向请求添加更多资金以用于交付和执行。不应在完成的请求上调用。

请参阅 Call 枚举及其相关变体以获取每个函数的文档。

运行时配置

以下示例显示了如何在您的运行时配置 pallet-ismp

use frame_support::parameter_types;
use frame_system::EnsureRoot;
use ismp::Error;
use pallet_ismp::NoOpMmrTree;
use ismp::host::StateMachine;
use ismp::module::IsmpModule;
use ismp::router::{IsmpRouter, Post, Response, Timeout};

parameter_types! {
    // The hyperbridge parachain on Polkadot
    pub const Coprocessor: Option<StateMachine> = Some(StateMachine::Polkadot(3367));
    // The host state machine of this pallet
    pub const HostStateMachine: StateMachine = StateMachine::Polkadot(1000); // your paraId here
}

impl pallet_ismp::Config for Runtime {
    // configure the runtime event
    type RuntimeEvent = RuntimeEvent;
    // Permissioned origin who can create or update consensus clients
    type AdminOrigin = EnsureRoot<AccountId>;
    // The state machine identifier for this state machine
    type HostStateMachine = HostStateMachine;
    // The pallet_timestamp pallet
    type TimestampProvider = Timestamp;
    // The currency implementation that is offered to relayers
    type Currency = Balances;
    // The balance type for the currency implementation
    type Balance = Balance;
    // Router implementation for routing requests/responses to their respective modules
    type Router = Router;
    // Optional coprocessor for incoming requests/responses
    type Coprocessor = Coprocessor;
    // Supported consensus clients
    type ConsensusClients = (
        // as an example, the parachain consensus client
        ismp_parachain::ParachainConsensusClient<Runtime, IsmpParachain>,
    );
    // Optional merkle mountain range overlay tree, for cheaper outgoing request proofs.
    // You most likely don't need it, just use the `NoOpMmrTree`
    type Mmr = NoOpMmrTree;
    // Weight provider for local modules
    type WeightProvider = ();
}

#[derive(Default)]
struct Router;
impl IsmpRouter for Router {
    fn module_for_id(&self, id: Vec<u8>) -> Result<Box<dyn IsmpModule>, Error> {
        let module = match id.as_slice() {
            YOUR_MODULE_ID => Box::new(YourModule::default()),
            _ => Err(Error::ModuleNotFound(id))?
        };
        Ok(module)
    }
}

/// Some custom module capable of processing some incoming/request or response.
/// This could also be a pallet itself.
#[derive(Default)]
struct YourModule;

pub const YOUR_MODULE_ID: &'static [u8] = &[12, 24, 36, 48];

impl IsmpModule for YourModule {
    /// Called by the ISMP hanlder, to notify module of a new POST request
    /// the module may choose to respond immediately, or in a later block
    fn on_accept(&self, request: Post) -> Result<(), Error> {
        // do something useful with the request
        Ok(())
    }

    /// Called by the ISMP hanlder, to notify module of a response to a previously
    /// sent out request
    fn on_response(&self, response: Response) -> Result<(), Error> {
        // do something useful with the response
        Ok(())
    }

    /// Called by the ISMP hanlder, to notify module of requests that were previously
    /// sent but have now timed-out
	fn on_timeout(&self, request: Timeout) -> Result<(), Error> {
        // revert any state changes that were made prior to dispatching the request
        Ok(())
    }
}

许可证

本库受Apache 2.0许可证许可,版权所有(c)2024 Polytope Labs。

依赖关系

~16–36MB
~586K SLoC