From 8a2503d7f5fb0db2f594eb111dfcd5fd076dea22 Mon Sep 17 00:00:00 2001 From: Sergej Date: Fri, 22 Aug 2025 18:04:34 +0200 Subject: [PATCH 1/5] Fix ISMP --- Cargo.lock | 34 ++++++++++++++++++- Cargo.toml | 2 ++ e2e_tests/xc-regions.common.ts | 5 +-- node/Cargo.toml | 3 ++ node/src/rpc.rs | 14 ++++++-- node/src/runtime_api.rs | 14 +++++++- node/src/service.rs | 11 +++++- runtime/kusama/Cargo.toml | 1 - runtime/kusama/src/lib.rs | 4 +-- .../xc-transfer/region-transfer.toml | 6 ++-- .../xc-transfer/region-transfer.zndsl | 2 +- 11 files changed, 81 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 64e96718..44b8614c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7475,6 +7475,21 @@ dependencies = [ "zeroize", ] +[[package]] +name = "mmr-gadget" +version = "29.0.1" +source = "git+https://github.com/polytope-labs/hyperbridge.git?tag=hyperbridge-v1.3.0#01c142e767b6856ea35bd36bbbe4ac5705a7ebae" +dependencies = [ + "futures", + "log", + "mmr-primitives", + "pallet-ismp", + "pallet-mmr-runtime-api", + "pallet-mmr-tree", + "parity-scale-codec", + "polkadot-sdk", +] + [[package]] name = "mmr-gadget" version = "43.0.0" @@ -9191,6 +9206,20 @@ dependencies = [ "sp-runtime", ] +[[package]] +name = "pallet-mmr-rpc" +version = "0.1.0" +source = "git+https://github.com/polytope-labs/hyperbridge.git?tag=hyperbridge-v1.3.0#01c142e767b6856ea35bd36bbbe4ac5705a7ebae" +dependencies = [ + "anyhow", + "jsonrpsee 0.24.9", + "pallet-ismp", + "pallet-ismp-rpc", + "pallet-mmr-runtime-api", + "parity-scale-codec", + "polkadot-sdk", +] + [[package]] name = "pallet-mmr-runtime-api" version = "0.1.1" @@ -11911,7 +11940,7 @@ dependencies = [ "kvdb", "kvdb-rocksdb", "log", - "mmr-gadget", + "mmr-gadget 43.0.0", "pallet-transaction-payment", "pallet-transaction-payment-rpc-runtime-api", "parity-db", @@ -13077,8 +13106,11 @@ dependencies = [ "ismp-parachain-runtime-api", "jsonrpsee 0.24.9", "log", + "mmr-gadget 29.0.1", + "pallet-ismp", "pallet-ismp-rpc", "pallet-ismp-runtime-api", + "pallet-mmr-rpc", "pallet-mmr-runtime-api", "parity-scale-codec", "polkadot-sdk", diff --git a/Cargo.toml b/Cargo.toml index 3cf17a47..720b0ac0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -49,6 +49,8 @@ pallet-ismp-runtime-api = { git = "https://github.com/polytope-labs/hyperbridge. ismp-parachain-runtime-api = { git = "https://github.com/polytope-labs/hyperbridge.git", tag = "hyperbridge-v1.3.0", default-features = false } pallet-mmr-tree = { git = "https://github.com/polytope-labs/hyperbridge.git", tag = "hyperbridge-v1.3.0", default-features = false } pallet-mmr-runtime-api = { git = "https://github.com/polytope-labs/hyperbridge.git", tag = "hyperbridge-v1.3.0", default-features = false } +pallet-mmr-rpc = { git = "https://github.com/polytope-labs/hyperbridge.git", tag = "hyperbridge-v1.3.0", default-features = false } +mmr-gadget = { git = "https://github.com/polytope-labs/hyperbridge.git", tag = "hyperbridge-v1.3.0", default-features = false } ismp-testsuite = { git = "https://github.com/polytope-labs/hyperbridge.git", tag = "hyperbridge-v1.3.0", default-features = false } # Local diff --git a/e2e_tests/xc-regions.common.ts b/e2e_tests/xc-regions.common.ts index fbc81d4f..7a12ffd8 100644 --- a/e2e_tests/xc-regions.common.ts +++ b/e2e_tests/xc-regions.common.ts @@ -4,6 +4,7 @@ import { getEncodedRegionId, RegionId } from 'coretime-utils'; import assert from 'node:assert'; import { sleep, submitExtrinsic, submitUnsigned } from './common'; import { makeIsmpResponse, queryRequest } from './ismp.common'; +import { encodeAddress } from '@polkadot/util-crypto'; const REGIONX_SOVEREIGN_ACCOUNT = '5Eg2fntJ27qsari4FGrGhrMqKFDRnkNSR6UshkZYBGXmSuC8'; @@ -76,7 +77,7 @@ async function transferRegionToRegionX( assert.deepStrictEqual(regions[0][0].toHuman(), [regionId]); let region = regions[0][1].toHuman() as any; - assert(region.owner == sender.address); + assert(encodeAddress(region.owner, 42) == encodeAddress(sender.address, 42)); assert(typeof region.record.Pending === 'string'); // Check the data on the Coretime chain: @@ -92,7 +93,7 @@ async function transferRegionToRegionX( // The record should be set after ISMP response: regions = await regionXApi.query.regions.regions.entries(); region = regions[0][1].toHuman() as any; - assert(region.owner == sender.address); + assert(encodeAddress(region.owner, 42) == encodeAddress(sender.address, 42)); } async function transferRegionToCoretimeChain( diff --git a/node/Cargo.toml b/node/Cargo.toml index c368941b..abdf8bb4 100644 --- a/node/Cargo.toml +++ b/node/Cargo.toml @@ -26,11 +26,14 @@ regionx-kusama-runtime = { workspace = true } regionx-runtime-common = { workspace = true } # Polytope Labs +pallet-ismp = { workspace = true, default-features = true } pallet-ismp-runtime-api = { workspace = true, default-features = true } pallet-ismp-rpc = { workspace = true, default-features = true } ismp-parachain-inherent = { workspace = true, default-features = true } ismp-parachain-runtime-api = { workspace = true, default-features = true } pallet-mmr-runtime-api = { workspace = true, default-features = true } +pallet-mmr-rpc = { workspace = true, default-features = true } +mmr-gadget = { workspace = true } [dependencies.polkadot-sdk] workspace = true diff --git a/node/src/rpc.rs b/node/src/rpc.rs index 1dd277a6..ae10eaa4 100644 --- a/node/src/rpc.rs +++ b/node/src/rpc.rs @@ -23,9 +23,8 @@ use polkadot_sdk::*; use std::sync::Arc; -use regionx_runtime_common::primitives::{opaque::Block, AccountId, Balance, Nonce}; +use regionx_runtime_common::primitives::{opaque::Block, AccountId, Balance, BlockNumber, Nonce}; -use pallet_ismp_rpc::{IsmpApiServer, IsmpRpcHandler}; use sc_client_api::{AuxStore, BlockBackend, ProofProvider}; use sc_transaction_pool_api::TransactionPool; use sp_api::ProvideRuntimeApi; @@ -64,10 +63,18 @@ where C::Api: substrate_frame_rpc_system::AccountNonceApi, C::Api: BlockBuilder, C::Api: pallet_ismp_runtime_api::IsmpRuntimeApi, + C::Api: pallet_mmr_runtime_api::MmrRuntimeApi< + Block, + H256, + BlockNumber, + pallet_ismp::offchain::Leaf, + >, P: TransactionPool + Sync + Send + 'static, B: sc_client_api::Backend + Send + Sync + 'static, B::State: sc_client_api::StateBackend>, { + use pallet_ismp_rpc::{IsmpApiServer, IsmpRpcHandler}; + use pallet_mmr_rpc::{MmrApiServer, MmrRpcHandler}; use pallet_transaction_payment_rpc::{TransactionPayment, TransactionPaymentApiServer}; use substrate_frame_rpc_system::{System, SystemApiServer}; @@ -76,7 +83,8 @@ where module.merge(System::new(client.clone(), pool).into_rpc())?; module.merge(TransactionPayment::new(client.clone()).into_rpc())?; - module.merge(IsmpRpcHandler::new(client, backend.clone())?.into_rpc())?; + module.merge(IsmpRpcHandler::new(client.clone(), backend.clone())?.into_rpc())?; + module.merge(MmrRpcHandler::new(client, backend.clone())?.into_rpc())?; Ok(module) } diff --git a/node/src/runtime_api.rs b/node/src/runtime_api.rs index 78ec3cb4..1083d098 100644 --- a/node/src/runtime_api.rs +++ b/node/src/runtime_api.rs @@ -16,7 +16,7 @@ use cumulus_primitives_core::CollectCollationInfo; use pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi; use polkadot_sdk::*; -use regionx_runtime_common::primitives::{AccountId, AuraId, Balance, Block, Nonce}; +use regionx_runtime_common::primitives::{AccountId, AuraId, Balance, Block, BlockNumber, Nonce}; use sc_offchain::OffchainWorkerApi; use sp_api::{ApiExt, Metadata}; use sp_block_builder::BlockBuilder; @@ -40,6 +40,12 @@ pub trait BaseHostRuntimeApis: + ismp_parachain_runtime_api::IsmpParachainApi + cumulus_primitives_aura::AuraUnincludedSegmentApi + pallet_ismp_runtime_api::IsmpRuntimeApi + + pallet_mmr_runtime_api::MmrRuntimeApi< + Block, + H256, + BlockNumber, + pallet_ismp::offchain::Leaf, + > { } @@ -57,5 +63,11 @@ impl BaseHostRuntimeApis for Api where + ismp_parachain_runtime_api::IsmpParachainApi + cumulus_primitives_aura::AuraUnincludedSegmentApi + pallet_ismp_runtime_api::IsmpRuntimeApi + + pallet_mmr_runtime_api::MmrRuntimeApi< + Block, + H256, + BlockNumber, + pallet_ismp::offchain::Leaf, + > { } diff --git a/node/src/service.rs b/node/src/service.rs index 2512c0de..5ecaddc5 100644 --- a/node/src/service.rs +++ b/node/src/service.rs @@ -133,7 +133,16 @@ where telemetry }); - // TODO: mmr gadget? + // Spawn mmr canonicalizing task + task_manager.spawn_handle().spawn( + "mmr-canonicalizing-gadget", + "mmr-gadget", + mmr_gadget::MmrGadget::start( + client.clone(), + backend.clone(), + sp_mmr_primitives::INDEXING_PREFIX.to_vec(), + ), + ); let transaction_pool = Arc::from( sc_transaction_pool::Builder::new( diff --git a/runtime/kusama/Cargo.toml b/runtime/kusama/Cargo.toml index fe52460d..4a3ee85f 100644 --- a/runtime/kusama/Cargo.toml +++ b/runtime/kusama/Cargo.toml @@ -136,7 +136,6 @@ runtime-benchmarks = [ "pallet-orders/runtime-benchmarks", "pallet-processor/runtime-benchmarks", "pallet-mmr-tree/runtime-benchmarks", - "pallet-mmr-tree/runtime-benchmarks", "cumulus-pallet-parachain-system/runtime-benchmarks", "pallet-ismp/runtime-benchmarks", "ismp-parachain/runtime-benchmarks", diff --git a/runtime/kusama/src/lib.rs b/runtime/kusama/src/lib.rs index 1a904bef..092dad8c 100644 --- a/runtime/kusama/src/lib.rs +++ b/runtime/kusama/src/lib.rs @@ -741,11 +741,11 @@ construct_runtime!( XcmpQueue: cumulus_pallet_xcmp_queue = 70, PolkadotXcm: pallet_xcm = 71, CumulusXcm: cumulus_pallet_xcm = 72, - MessageQueue: pallet_message_queue = 73, // ISMP - Ismp: pallet_ismp = 80, Mmr: pallet_mmr_tree = 81, + Ismp: pallet_ismp = 80, + MessageQueue: pallet_message_queue = 73, IsmpParachain: ismp_parachain = 82, // Main stage: diff --git a/zombienet_tests/xc-transfer/region-transfer.toml b/zombienet_tests/xc-transfer/region-transfer.toml index 61f83839..217dd4a2 100644 --- a/zombienet_tests/xc-transfer/region-transfer.toml +++ b/zombienet_tests/xc-transfer/region-transfer.toml @@ -2,8 +2,8 @@ timeout = 1000 [relaychain] -chain = "kusama-local" -chain_spec_command = "chain-spec-generator {% raw %} {{chainName}} {% endraw %}" +chain = "rococo-local" +# chain_spec_command = "chain-spec-generator {% raw %} {{chainName}} {% endraw %}" command = "polkadot" [[relaychain.nodes]] @@ -35,4 +35,4 @@ addToGenesis = false [parachains.collator] name = "regionx-collator01" command = "regionx-node" - args = [ "--enable-offchain-indexing true --log=xcm=trace,regions=trace" ] + args = [ "--enable-offchain-indexing true --log=xcm=trace,ismp=trace,regions=trace" ] diff --git a/zombienet_tests/xc-transfer/region-transfer.zndsl b/zombienet_tests/xc-transfer/region-transfer.zndsl index 78a5a0cc..2f3f6285 100644 --- a/zombienet_tests/xc-transfer/region-transfer.zndsl +++ b/zombienet_tests/xc-transfer/region-transfer.zndsl @@ -9,4 +9,4 @@ kusama-validator01: parachain 2000 is registered within 225 seconds regionx-collator01: js-script ../../e2e_tests/build/xc-transfer/region-transfer.js return is 0 within 600 seconds -sleep 200 seconds +sleep 2000 seconds From 7a557f2778771ec77394b46536910ceba292ca7a Mon Sep 17 00:00:00 2001 From: Sergej Date: Mon, 25 Aug 2025 13:20:48 +0200 Subject: [PATCH 2/5] don't use mmr --- Cargo.lock | 85 +------------------------------------- Cargo.toml | 4 -- node/Cargo.toml | 4 -- node/src/rpc.rs | 12 +----- node/src/runtime_api.rs | 14 +------ node/src/service.rs | 11 ----- runtime/kusama/Cargo.toml | 7 ---- runtime/kusama/src/ismp.rs | 12 +++--- runtime/kusama/src/lib.rs | 39 ----------------- 9 files changed, 11 insertions(+), 177 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 44b8614c..53eaca62 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1885,15 +1885,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "ckb-merkle-mountain-range" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56ccb671c5921be8a84686e6212ca184cb1d7c51cadcdbfcbd1cc3f042f5dfb8" -dependencies = [ - "cfg-if", -] - [[package]] name = "clang-sys" version = "1.8.1" @@ -7475,21 +7466,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "mmr-gadget" -version = "29.0.1" -source = "git+https://github.com/polytope-labs/hyperbridge.git?tag=hyperbridge-v1.3.0#01c142e767b6856ea35bd36bbbe4ac5705a7ebae" -dependencies = [ - "futures", - "log", - "mmr-primitives", - "pallet-ismp", - "pallet-mmr-runtime-api", - "pallet-mmr-tree", - "parity-scale-codec", - "polkadot-sdk", -] - [[package]] name = "mmr-gadget" version = "43.0.0" @@ -7510,20 +7486,6 @@ dependencies = [ "sp-runtime", ] -[[package]] -name = "mmr-primitives" -version = "1.15.2" -source = "git+https://github.com/polytope-labs/hyperbridge.git?tag=hyperbridge-v1.3.0#01c142e767b6856ea35bd36bbbe4ac5705a7ebae" -dependencies = [ - "ckb-merkle-mountain-range", - "ismp", - "pallet-ismp", - "parity-scale-codec", - "polkadot-sdk", - "scale-info", - "serde", -] - [[package]] name = "mmr-rpc" version = "39.0.0" @@ -9206,46 +9168,6 @@ dependencies = [ "sp-runtime", ] -[[package]] -name = "pallet-mmr-rpc" -version = "0.1.0" -source = "git+https://github.com/polytope-labs/hyperbridge.git?tag=hyperbridge-v1.3.0#01c142e767b6856ea35bd36bbbe4ac5705a7ebae" -dependencies = [ - "anyhow", - "jsonrpsee 0.24.9", - "pallet-ismp", - "pallet-ismp-rpc", - "pallet-mmr-runtime-api", - "parity-scale-codec", - "polkadot-sdk", -] - -[[package]] -name = "pallet-mmr-runtime-api" -version = "0.1.1" -source = "git+https://github.com/polytope-labs/hyperbridge.git?tag=hyperbridge-v1.3.0#01c142e767b6856ea35bd36bbbe4ac5705a7ebae" -dependencies = [ - "pallet-ismp", - "parity-scale-codec", - "polkadot-sdk", - "serde", -] - -[[package]] -name = "pallet-mmr-tree" -version = "0.1.1" -source = "git+https://github.com/polytope-labs/hyperbridge.git?tag=hyperbridge-v1.3.0#01c142e767b6856ea35bd36bbbe4ac5705a7ebae" -dependencies = [ - "ckb-merkle-mountain-range", - "log", - "mmr-primitives", - "pallet-ismp", - "parity-scale-codec", - "polkadot-sdk", - "scale-info", - "serde", -] - [[package]] name = "pallet-multisig" version = "39.1.1" @@ -11940,7 +11862,7 @@ dependencies = [ "kvdb", "kvdb-rocksdb", "log", - "mmr-gadget 43.0.0", + "mmr-gadget", "pallet-transaction-payment", "pallet-transaction-payment-rpc-runtime-api", "parity-db", @@ -13081,8 +13003,6 @@ dependencies = [ "pallet-ismp", "pallet-ismp-runtime-api", "pallet-market", - "pallet-mmr-runtime-api", - "pallet-mmr-tree", "pallet-orders", "pallet-processor", "pallet-regions", @@ -13106,12 +13026,9 @@ dependencies = [ "ismp-parachain-runtime-api", "jsonrpsee 0.24.9", "log", - "mmr-gadget 29.0.1", "pallet-ismp", "pallet-ismp-rpc", "pallet-ismp-runtime-api", - "pallet-mmr-rpc", - "pallet-mmr-runtime-api", "parity-scale-codec", "polkadot-sdk", "regionx-kusama-runtime", diff --git a/Cargo.toml b/Cargo.toml index 720b0ac0..2fdb7083 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -47,10 +47,6 @@ ismp-parachain = { git = "https://github.com/polytope-labs/hyperbridge.git", tag ismp-parachain-inherent = { git = "https://github.com/polytope-labs/hyperbridge.git", tag = "hyperbridge-v1.3.0", default-features = false } pallet-ismp-runtime-api = { git = "https://github.com/polytope-labs/hyperbridge.git", tag = "hyperbridge-v1.3.0", default-features = false } ismp-parachain-runtime-api = { git = "https://github.com/polytope-labs/hyperbridge.git", tag = "hyperbridge-v1.3.0", default-features = false } -pallet-mmr-tree = { git = "https://github.com/polytope-labs/hyperbridge.git", tag = "hyperbridge-v1.3.0", default-features = false } -pallet-mmr-runtime-api = { git = "https://github.com/polytope-labs/hyperbridge.git", tag = "hyperbridge-v1.3.0", default-features = false } -pallet-mmr-rpc = { git = "https://github.com/polytope-labs/hyperbridge.git", tag = "hyperbridge-v1.3.0", default-features = false } -mmr-gadget = { git = "https://github.com/polytope-labs/hyperbridge.git", tag = "hyperbridge-v1.3.0", default-features = false } ismp-testsuite = { git = "https://github.com/polytope-labs/hyperbridge.git", tag = "hyperbridge-v1.3.0", default-features = false } # Local diff --git a/node/Cargo.toml b/node/Cargo.toml index abdf8bb4..581b0acf 100644 --- a/node/Cargo.toml +++ b/node/Cargo.toml @@ -31,9 +31,6 @@ pallet-ismp-runtime-api = { workspace = true, default-features = true } pallet-ismp-rpc = { workspace = true, default-features = true } ismp-parachain-inherent = { workspace = true, default-features = true } ismp-parachain-runtime-api = { workspace = true, default-features = true } -pallet-mmr-runtime-api = { workspace = true, default-features = true } -pallet-mmr-rpc = { workspace = true, default-features = true } -mmr-gadget = { workspace = true } [dependencies.polkadot-sdk] workspace = true @@ -74,7 +71,6 @@ features = [ "sp-transaction-pool", "substrate-frame-rpc-system", "substrate-prometheus-endpoint", - "sp-mmr-primitives", "frame-metadata-hash-extension", "polkadot-cli", "polkadot-primitives", diff --git a/node/src/rpc.rs b/node/src/rpc.rs index ae10eaa4..cbb07848 100644 --- a/node/src/rpc.rs +++ b/node/src/rpc.rs @@ -23,7 +23,7 @@ use polkadot_sdk::*; use std::sync::Arc; -use regionx_runtime_common::primitives::{opaque::Block, AccountId, Balance, BlockNumber, Nonce}; +use regionx_runtime_common::primitives::{opaque::Block, AccountId, Balance, Nonce}; use sc_client_api::{AuxStore, BlockBackend, ProofProvider}; use sc_transaction_pool_api::TransactionPool; @@ -63,18 +63,11 @@ where C::Api: substrate_frame_rpc_system::AccountNonceApi, C::Api: BlockBuilder, C::Api: pallet_ismp_runtime_api::IsmpRuntimeApi, - C::Api: pallet_mmr_runtime_api::MmrRuntimeApi< - Block, - H256, - BlockNumber, - pallet_ismp::offchain::Leaf, - >, P: TransactionPool + Sync + Send + 'static, B: sc_client_api::Backend + Send + Sync + 'static, B::State: sc_client_api::StateBackend>, { use pallet_ismp_rpc::{IsmpApiServer, IsmpRpcHandler}; - use pallet_mmr_rpc::{MmrApiServer, MmrRpcHandler}; use pallet_transaction_payment_rpc::{TransactionPayment, TransactionPaymentApiServer}; use substrate_frame_rpc_system::{System, SystemApiServer}; @@ -83,8 +76,7 @@ where module.merge(System::new(client.clone(), pool).into_rpc())?; module.merge(TransactionPayment::new(client.clone()).into_rpc())?; - module.merge(IsmpRpcHandler::new(client.clone(), backend.clone())?.into_rpc())?; - module.merge(MmrRpcHandler::new(client, backend.clone())?.into_rpc())?; + module.merge(IsmpRpcHandler::new(client, backend.clone())?.into_rpc())?; Ok(module) } diff --git a/node/src/runtime_api.rs b/node/src/runtime_api.rs index 1083d098..78ec3cb4 100644 --- a/node/src/runtime_api.rs +++ b/node/src/runtime_api.rs @@ -16,7 +16,7 @@ use cumulus_primitives_core::CollectCollationInfo; use pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi; use polkadot_sdk::*; -use regionx_runtime_common::primitives::{AccountId, AuraId, Balance, Block, BlockNumber, Nonce}; +use regionx_runtime_common::primitives::{AccountId, AuraId, Balance, Block, Nonce}; use sc_offchain::OffchainWorkerApi; use sp_api::{ApiExt, Metadata}; use sp_block_builder::BlockBuilder; @@ -40,12 +40,6 @@ pub trait BaseHostRuntimeApis: + ismp_parachain_runtime_api::IsmpParachainApi + cumulus_primitives_aura::AuraUnincludedSegmentApi + pallet_ismp_runtime_api::IsmpRuntimeApi - + pallet_mmr_runtime_api::MmrRuntimeApi< - Block, - H256, - BlockNumber, - pallet_ismp::offchain::Leaf, - > { } @@ -63,11 +57,5 @@ impl BaseHostRuntimeApis for Api where + ismp_parachain_runtime_api::IsmpParachainApi + cumulus_primitives_aura::AuraUnincludedSegmentApi + pallet_ismp_runtime_api::IsmpRuntimeApi - + pallet_mmr_runtime_api::MmrRuntimeApi< - Block, - H256, - BlockNumber, - pallet_ismp::offchain::Leaf, - > { } diff --git a/node/src/service.rs b/node/src/service.rs index 5ecaddc5..224414e4 100644 --- a/node/src/service.rs +++ b/node/src/service.rs @@ -133,17 +133,6 @@ where telemetry }); - // Spawn mmr canonicalizing task - task_manager.spawn_handle().spawn( - "mmr-canonicalizing-gadget", - "mmr-gadget", - mmr_gadget::MmrGadget::start( - client.clone(), - backend.clone(), - sp_mmr_primitives::INDEXING_PREFIX.to_vec(), - ), - ); - let transaction_pool = Arc::from( sc_transaction_pool::Builder::new( task_manager.spawn_essential_handle(), diff --git a/runtime/kusama/Cargo.toml b/runtime/kusama/Cargo.toml index 4a3ee85f..fb3b1327 100644 --- a/runtime/kusama/Cargo.toml +++ b/runtime/kusama/Cargo.toml @@ -36,9 +36,6 @@ ismp-parachain = { workspace = true } pallet-ismp-runtime-api = { workspace = true } ismp-parachain-runtime-api = { workspace = true } -pallet-mmr-tree = { workspace = true } -pallet-mmr-runtime-api = { workspace = true } - cumulus-pallet-parachain-system = { workspace = true } frame-benchmarking = { workspace = true, optional = true } @@ -80,7 +77,6 @@ features = [ "sp-std", "sp-transaction-pool", "sp-version", - "sp-mmr-primitives", "pallet-xcm", "polkadot-parachain-primitives", "polkadot-runtime-common", @@ -113,8 +109,6 @@ std = [ "polkadot-sdk/std", "pallet-ismp/std", "pallet-ismp-runtime-api/std", - "pallet-mmr-tree/std", - "pallet-mmr-runtime-api/std", "pallet-market/std", "pallet-orders/std", "pallet-processor/std", @@ -135,7 +129,6 @@ runtime-benchmarks = [ "pallet-market/runtime-benchmarks", "pallet-orders/runtime-benchmarks", "pallet-processor/runtime-benchmarks", - "pallet-mmr-tree/runtime-benchmarks", "cumulus-pallet-parachain-system/runtime-benchmarks", "pallet-ismp/runtime-benchmarks", "ismp-parachain/runtime-benchmarks", diff --git a/runtime/kusama/src/ismp.rs b/runtime/kusama/src/ismp.rs index 76d63896..d53c84a0 100644 --- a/runtime/kusama/src/ismp.rs +++ b/runtime/kusama/src/ismp.rs @@ -14,7 +14,7 @@ // along with RegionX. If not, see . use crate::{ - weights::ismp_parachain, AccountId, Balance, Balances, Ismp, IsmpParachain, Mmr, ParachainInfo, + weights::ismp_parachain, AccountId, Balance, Balances, Ismp, IsmpParachain, ParachainInfo, Runtime, RuntimeEvent, Timestamp, }; use ::ismp_parachain::ParachainConsensusClient; @@ -33,9 +33,11 @@ impl Get for HostStateMachine { } } -parameter_types! { - // The hyperbridge parachain on Polkadot - pub const Coprocessor: Option = None; +pub struct Coprocessor; +impl Get> for Coprocessor { + fn get() -> Option { + Some(HostStateMachine::get()) + } } impl ::ismp_parachain::Config for Runtime { @@ -54,7 +56,7 @@ impl pallet_ismp::Config for Runtime { type Currency = Balances; type Coprocessor = Coprocessor; type ConsensusClients = (ParachainConsensusClient,); - type OffchainDB = Mmr; + type OffchainDB = (); type FeeHandler = pallet_ismp::fee_handler::WeightFeeHandler<()>; } diff --git a/runtime/kusama/src/lib.rs b/runtime/kusama/src/lib.rs index 092dad8c..2ac9e1c1 100644 --- a/runtime/kusama/src/lib.rs +++ b/runtime/kusama/src/lib.rs @@ -93,10 +93,8 @@ use frame_system::{ limits::{BlockLength, BlockWeights}, EnsureRoot, }; -use pallet_ismp::offchain::{Leaf, Proof, ProofKeys}; use pallet_xcm::{EnsureXcm, IsVoiceOfBody}; use sp_core::H256; -use sp_mmr_primitives::INDEXING_PREFIX; pub use sp_runtime::{MultiAddress, Perbill, Permill}; use xcm_config::XcmOriginToTransactDispatchOrigin; @@ -114,7 +112,6 @@ use xcm::latest::prelude::BodyId; use regionx_runtime_common::primitives::{ AccountId, Address, AuraId, Balance, BlockNumber, Hash, Header, Nonce, Signature, }; -use sp_mmr_primitives::LeafIndex; pub type Block = generic::Block; /// A Block signed with a Justification @@ -697,13 +694,6 @@ impl pallet_processor::Config for Runtime { type WeightInfo = weights::pallet_processor::WeightInfo; } -impl pallet_mmr_tree::Config for Runtime { - const INDEXING_PREFIX: &'static [u8] = INDEXING_PREFIX; - type Hashing = BlakeTwo256; // Should we use keccak256? - type Leaf = Leaf; - type ForkIdentifierProvider = Ismp; -} - // Create the runtime by composing the FRAME pallets that were previously configured. construct_runtime!( pub enum Runtime @@ -743,7 +733,6 @@ construct_runtime!( CumulusXcm: cumulus_pallet_xcm = 72, // ISMP - Mmr: pallet_mmr_tree = 81, Ismp: pallet_ismp = 80, MessageQueue: pallet_message_queue = 73, IsmpParachain: ismp_parachain = 82, @@ -946,34 +935,6 @@ impl_runtime_apis! { } } - impl pallet_mmr_runtime_api::MmrRuntimeApi::Hash, BlockNumber, Leaf> for Runtime { - /// Return Block number where pallet-mmr was added to the runtime - fn pallet_genesis() -> Result, sp_mmr_primitives::Error> { - Ok(Mmr::initial_height()) - } - - /// Return the number of MMR leaves. - fn mmr_leaf_count() -> Result { - Ok(Mmr::leaf_count()) - } - - /// Return the on-chain MMR root hash. - fn mmr_root() -> Result { - Ok(Mmr::mmr_root_hash()) - } - - fn fork_identifier() -> Result { - Ok(Ismp::child_trie_root()) - } - - /// Generate a proof for the provided leaf indices - fn generate_proof( - keys: ProofKeys - ) -> Result<(Vec, Proof<::Hash>), sp_mmr_primitives::Error> { - Mmr::generate_proof(keys) - } - } - impl cumulus_primitives_core::CollectCollationInfo for Runtime { fn collect_collation_info(header: &::Header) -> cumulus_primitives_core::CollationInfo { ParachainSystem::collect_collation_info(header) From 52b17f0441ea8451cafcb80f56c22bed4b2fd6de Mon Sep 17 00:00:00 2001 From: Sergej Date: Thu, 28 Aug 2025 12:40:55 +0200 Subject: [PATCH 3/5] progress --- e2e_tests/ismp.common.ts | 72 +++++++++---------- e2e_tests/types.ts | 21 ++++-- e2e_tests/xc-regions.common.ts | 7 +- .../xc-transfer/region-transfer.toml | 4 +- 4 files changed, 53 insertions(+), 51 deletions(-) diff --git a/e2e_tests/ismp.common.ts b/e2e_tests/ismp.common.ts index 40990d24..c0f6d3d2 100644 --- a/e2e_tests/ismp.common.ts +++ b/e2e_tests/ismp.common.ts @@ -2,6 +2,9 @@ import { ApiPromise } from '@polkadot/api'; import { KeyringPair } from '@polkadot/keyring/types'; import { submitExtrinsic, submitUnsigned } from './common'; import { Get, IsmpRequest } from './types'; +import { hexToU8a } from '@polkadot/util'; +import { SubmittableExtrinsic } from '@polkadot/api/types'; +import { IGetRequest, SubstrateChain } from './hyperbridge-sdk'; async function ismpAddParachain(signer: KeyringPair, regionXApi: ApiPromise) { const addParaCall = regionXApi.tx.ismpParachain.addParachain([{ id: 1005, slotDuration: 6000 }]); @@ -9,57 +12,46 @@ async function ismpAddParachain(signer: KeyringPair, regionXApi: ApiPromise) { return submitExtrinsic(signer, sudoCall, {}); } -async function queryRequest(regionxApi: ApiPromise, commitment: string): Promise { +async function queryRequest(regionxApi: ApiPromise, commitment: string): Promise { const leafIndex = regionxApi.createType('LeafIndexQuery', { commitment }); const requests = await (regionxApi as any).rpc.ismp.queryRequests([leafIndex]); // We only requested a single request so we only get one in the response. - return requests.toJSON()[0] as IsmpRequest; + console.log(requests.toJSON()); + return requests.toJSON()[0].get as IGetRequest; } async function makeIsmpResponse( - regionXApi: ApiPromise, + regionxWs: string, coretimeApi: ApiPromise, - request: IsmpRequest, + request: IGetRequest, responderAddress: string ): Promise { - if (isGetRequest(request)) { - const hashAt = ( - await coretimeApi.query.system.blockHash(Number(request.get.height)) - ).toString(); - const proofData = await coretimeApi.rpc.state.getReadProof([request.get.keys[0]], hashAt); + const hashAt = ( + await coretimeApi.query.system.blockHash(Number(request.height)) + ).toString(); + const proofData = await coretimeApi.rpc.state.getReadProof([request.keys[0]], hashAt); - const stateMachineProof = regionXApi.createType('StateMachineProof', { - hasher: 'Blake2', - storage_proof: proofData.proof, - }); + const regionx = new SubstrateChain({ + ws: regionxWs, + hasher: 'Blake2', + }); - const substrateStateProof = regionXApi.createType('SubstrateStateProof', { - StateProof: stateMachineProof, - }); - const response = regionXApi.tx.ismp.handleUnsigned([ - { - Response: { - datagram: { - Request: [request], - }, - proof: { - height: { - id: { - stateId: 1005, - consensusStateId: 'PAS0', - }, - height: request.get.height.toString(), - }, - proof: substrateStateProof.toHex(), - }, - signer: responderAddress, - }, - }, - ]); - await submitUnsigned(response); - } else { - new Error('Expected a Get request'); - } + const tx = regionx.encode({ + kind: 'GetResponse', + proof: { + consensusStateId: 'PAS0', + height: request.height, + proof: proofData.toHex(), + stateMachine: 'KUSAMA-1005' + }, + responses: [{get: request, values: [{key: request.keys[0], value: '0x0'}] }], + signer: responderAddress as any + }); + + const call = regionx.api?.tx.ismp.handleUnsigned(hexToU8a(tx).slice(2)) as SubmittableExtrinsic<'promise'> | undefined; + if(!call) return; + + await submitUnsigned(call); } const isGetRequest = (request: IsmpRequest): request is { get: Get } => { diff --git a/e2e_tests/types.ts b/e2e_tests/types.ts index 94719760..16403e98 100644 --- a/e2e_tests/types.ts +++ b/e2e_tests/types.ts @@ -1,8 +1,8 @@ export type StateMachine = { Polkadot: number } | { Kusama: number }; export interface Get { - source: StateMachine; - dest: StateMachine; + source: string; + dest: string; nonce: bigint; from: string; keys: Array; @@ -42,21 +42,30 @@ export const REGIONX_API_TYPES = { LeafIndexQuery: { commitment: 'H256', }, + ConsensusStateId: '[u8; 4]', + Relay: { + relay: 'ConsensusStateId', + para_id: 'u32' + }, StateMachine: { _enum: { - Ethereum: 'Vec', + Evm: 'u32', Polkadot: 'u32', Kusama: 'u32', - }, + Substrate: 'ConsensusStateId', + Tendermint: 'ConsensusStateId', + Relay: 'Relay' + } }, Post: {}, Get: { - source: 'StateMachine', - dest: 'StateMachine', + source: 'Text', + dest: 'Text', nonce: 'u64', from: 'Vec', keys: 'Vec>', height: 'u64', + context: 'Vec', timeout_timestamp: 'u64', }, Request: { diff --git a/e2e_tests/xc-regions.common.ts b/e2e_tests/xc-regions.common.ts index 7a12ffd8..c1d4aaba 100644 --- a/e2e_tests/xc-regions.common.ts +++ b/e2e_tests/xc-regions.common.ts @@ -11,6 +11,7 @@ const REGIONX_SOVEREIGN_ACCOUNT = '5Eg2fntJ27qsari4FGrGhrMqKFDRnkNSR6UshkZYBGXmS async function transferRegionToRegionX( coretimeApi: ApiPromise, regionXApi: ApiPromise, + regionxWs: string, sender: KeyringPair, regionId: RegionId ) { @@ -76,7 +77,7 @@ async function transferRegionToRegionX( assert.equal(regions.length, 1); assert.deepStrictEqual(regions[0][0].toHuman(), [regionId]); - let region = regions[0][1].toHuman() as any; + const region = regions[0][1].toHuman() as any; assert(encodeAddress(region.owner, 42) == encodeAddress(sender.address, 42)); assert(typeof region.record.Pending === 'string'); @@ -88,12 +89,14 @@ async function transferRegionToRegionX( // Respond to the ISMP get request: const request = await queryRequest(regionXApi, region.record.Pending); - await makeIsmpResponse(regionXApi, coretimeApi, request, sender.address); + await makeIsmpResponse(regionxWs, coretimeApi, request, sender.address); + /* // The record should be set after ISMP response: regions = await regionXApi.query.regions.regions.entries(); region = regions[0][1].toHuman() as any; assert(encodeAddress(region.owner, 42) == encodeAddress(sender.address, 42)); + */ } async function transferRegionToCoretimeChain( diff --git a/zombienet_tests/xc-transfer/region-transfer.toml b/zombienet_tests/xc-transfer/region-transfer.toml index 217dd4a2..34b4ea82 100644 --- a/zombienet_tests/xc-transfer/region-transfer.toml +++ b/zombienet_tests/xc-transfer/region-transfer.toml @@ -8,12 +8,10 @@ command = "polkadot" [[relaychain.nodes]] name = "kusama-validator01" - args = [ "--log=xcm=trace" ] validator = true [[relaychain.nodes]] name = "kusama-validator02" - args = [ "--log=xcm=trace" ] validator = true [[parachains]] @@ -35,4 +33,4 @@ addToGenesis = false [parachains.collator] name = "regionx-collator01" command = "regionx-node" - args = [ "--enable-offchain-indexing true --log=xcm=trace,ismp=trace,regions=trace" ] + args = [ "--enable-offchain-indexing true --log=ismp=trace,regions=trace" ] From 21e53448e3e96ff2bf59e7fdd88913ca052f6d96 Mon Sep 17 00:00:00 2001 From: Sergej Date: Mon, 1 Sep 2025 12:14:21 +0200 Subject: [PATCH 4/5] progress --- e2e_tests/ismp.common.ts | 77 +++++++++++++------ e2e_tests/types.ts | 3 + e2e_tests/xc-regions.common.ts | 5 +- e2e_tests/xc-transfer/region-transfer.ts | 2 +- runtime/kusama/src/ismp.rs | 1 + .../xc-transfer/region-transfer.toml | 2 +- 6 files changed, 62 insertions(+), 28 deletions(-) diff --git a/e2e_tests/ismp.common.ts b/e2e_tests/ismp.common.ts index c0f6d3d2..a417a042 100644 --- a/e2e_tests/ismp.common.ts +++ b/e2e_tests/ismp.common.ts @@ -2,9 +2,6 @@ import { ApiPromise } from '@polkadot/api'; import { KeyringPair } from '@polkadot/keyring/types'; import { submitExtrinsic, submitUnsigned } from './common'; import { Get, IsmpRequest } from './types'; -import { hexToU8a } from '@polkadot/util'; -import { SubmittableExtrinsic } from '@polkadot/api/types'; -import { IGetRequest, SubstrateChain } from './hyperbridge-sdk'; async function ismpAddParachain(signer: KeyringPair, regionXApi: ApiPromise) { const addParaCall = regionXApi.tx.ismpParachain.addParachain([{ id: 1005, slotDuration: 6000 }]); @@ -12,46 +9,78 @@ async function ismpAddParachain(signer: KeyringPair, regionXApi: ApiPromise) { return submitExtrinsic(signer, sudoCall, {}); } -async function queryRequest(regionxApi: ApiPromise, commitment: string): Promise { +async function queryRequest(regionxApi: ApiPromise, commitment: string): Promise { const leafIndex = regionxApi.createType('LeafIndexQuery', { commitment }); const requests = await (regionxApi as any).rpc.ismp.queryRequests([leafIndex]); // We only requested a single request so we only get one in the response. console.log(requests.toJSON()); - return requests.toJSON()[0].get as IGetRequest; + return requests.toJSON()[0] as IsmpRequest; } async function makeIsmpResponse( - regionxWs: string, + regionXApi: ApiPromise, coretimeApi: ApiPromise, - request: IGetRequest, + request: IsmpRequest, responderAddress: string ): Promise { + console.log(request); + if (!isGetRequest(request)) { + console.log('not get request'); + new Error('Expected a Get request'); + return; + } + const hashAt = ( - await coretimeApi.query.system.blockHash(Number(request.height)) + await coretimeApi.query.system.blockHash(Number(request.get.height)) ).toString(); - const proofData = await coretimeApi.rpc.state.getReadProof([request.keys[0]], hashAt); + const proofData = await coretimeApi.rpc.state.getReadProof([request.get.keys[0]], hashAt); - const regionx = new SubstrateChain({ - ws: regionxWs, + const stateMachineProof = regionXApi.createType('StateMachineProof', { hasher: 'Blake2', + storage_proof: proofData.proof, }); - const tx = regionx.encode({ - kind: 'GetResponse', - proof: { - consensusStateId: 'PAS0', - height: request.height, - proof: proofData.toHex(), - stateMachine: 'KUSAMA-1005' - }, - responses: [{get: request, values: [{key: request.keys[0], value: '0x0'}] }], - signer: responderAddress as any + const substrateStateProof = regionXApi.createType('SubstrateStateProof', { + StateProof: stateMachineProof, }); - const call = regionx.api?.tx.ismp.handleUnsigned(hexToU8a(tx).slice(2)) as SubmittableExtrinsic<'promise'> | undefined; - if(!call) return; + // The issue is that requests are empty. That is why it is passing as well... + // At least we know handleUnsigned is handled successfully with zero requests. + const response = [{ + Response: { + datagram: { + Request: [{ + Get: { + source: { Kusama: 2000 }, + dest: { Kusama: 1005 }, + nonce: request.get.nonce, + from: request.get.from, + keys: request.get.keys, + height: request.get.height, + context: request.get.context, + timeoutTimestamp: request.get.timeout_timestamp, + } + }], + }, + proof: { + height: { + id: { + stateId: { + Kusama: 1005, + }, + consensusStateId: 'PAS0', + }, + height: request.get.height.toString(), + }, + proof: substrateStateProof.toHex(), + }, + signer: responderAddress, + }, + }]; + + console.log(response); - await submitUnsigned(call); + await submitUnsigned(regionXApi.tx.ismp.handleUnsigned(response)); } const isGetRequest = (request: IsmpRequest): request is { get: Get } => { diff --git a/e2e_tests/types.ts b/e2e_tests/types.ts index 16403e98..99d895a2 100644 --- a/e2e_tests/types.ts +++ b/e2e_tests/types.ts @@ -1,3 +1,5 @@ +import { Enum, Struct, u32, u64, u8, Vector, Option } from "scale-ts"; + export type StateMachine = { Polkadot: number } | { Kusama: number }; export interface Get { @@ -7,6 +9,7 @@ export interface Get { from: string; keys: Array; height: bigint; + context: string; timeout_timestamp: bigint; } diff --git a/e2e_tests/xc-regions.common.ts b/e2e_tests/xc-regions.common.ts index c1d4aaba..f8e5006c 100644 --- a/e2e_tests/xc-regions.common.ts +++ b/e2e_tests/xc-regions.common.ts @@ -11,7 +11,6 @@ const REGIONX_SOVEREIGN_ACCOUNT = '5Eg2fntJ27qsari4FGrGhrMqKFDRnkNSR6UshkZYBGXmS async function transferRegionToRegionX( coretimeApi: ApiPromise, regionXApi: ApiPromise, - regionxWs: string, sender: KeyringPair, regionId: RegionId ) { @@ -89,7 +88,9 @@ async function transferRegionToRegionX( // Respond to the ISMP get request: const request = await queryRequest(regionXApi, region.record.Pending); - await makeIsmpResponse(regionxWs, coretimeApi, request, sender.address); + await makeIsmpResponse(regionXApi, coretimeApi, request, encodeAddress(sender.address, 74)); + + await sleep(360 * 1000); /* // The record should be set after ISMP response: diff --git a/e2e_tests/xc-transfer/region-transfer.ts b/e2e_tests/xc-transfer/region-transfer.ts index 639df973..cc6764e1 100644 --- a/e2e_tests/xc-transfer/region-transfer.ts +++ b/e2e_tests/xc-transfer/region-transfer.ts @@ -46,7 +46,7 @@ async function run(_nodeName: any, networkInfo: any, _jsArgs: any) { // Transferring back to the Coretime chain should work: // NOTE: the function contains checks, and if any of them fail, the test will fail. - await transferRegionToCoretimeChain(coretimeApi, regionXApi, alice, regionId); + // await transferRegionToCoretimeChain(coretimeApi, regionXApi, alice, regionId); } export { run }; diff --git a/runtime/kusama/src/ismp.rs b/runtime/kusama/src/ismp.rs index d53c84a0..aa0bf3e9 100644 --- a/runtime/kusama/src/ismp.rs +++ b/runtime/kusama/src/ismp.rs @@ -64,6 +64,7 @@ impl pallet_ismp::Config for Runtime { pub struct Router; impl IsmpRouter for Router { fn module_for_id(&self, id: Vec) -> Result, anyhow::Error> { + info!(target: "regionx::ismp", "Module_for_id: {:?}", id); let module = match ModuleId::from_bytes(&id) { Ok(pallet_regions::PALLET_ID) => Box::>::default(), diff --git a/zombienet_tests/xc-transfer/region-transfer.toml b/zombienet_tests/xc-transfer/region-transfer.toml index 34b4ea82..969c2737 100644 --- a/zombienet_tests/xc-transfer/region-transfer.toml +++ b/zombienet_tests/xc-transfer/region-transfer.toml @@ -33,4 +33,4 @@ addToGenesis = false [parachains.collator] name = "regionx-collator01" command = "regionx-node" - args = [ "--enable-offchain-indexing true --log=ismp=trace,regions=trace" ] + args = [ "--enable-offchain-indexing true --log=ismp=trace,regionx::ismp=trace,regions=trace" ] From ee63e46226a81fe5149d803c0c544a4157c1454c Mon Sep 17 00:00:00 2001 From: Sergej Date: Sat, 6 Sep 2025 23:45:38 +0200 Subject: [PATCH 5/5] progress --- e2e_tests/ismp.common.ts | 66 ++++++++++++++++++++---- e2e_tests/types.ts | 4 +- e2e_tests/xc-regions.common.ts | 3 +- e2e_tests/xc-transfer/region-transfer.ts | 34 +++++++++++- package.json | 6 +-- runtime/kusama/src/ismp.rs | 1 - 6 files changed, 96 insertions(+), 18 deletions(-) diff --git a/e2e_tests/ismp.common.ts b/e2e_tests/ismp.common.ts index a417a042..07c40f42 100644 --- a/e2e_tests/ismp.common.ts +++ b/e2e_tests/ismp.common.ts @@ -1,7 +1,9 @@ import { ApiPromise } from '@polkadot/api'; import { KeyringPair } from '@polkadot/keyring/types'; -import { submitExtrinsic, submitUnsigned } from './common'; +import { sleep, submitExtrinsic, submitUnsigned } from './common'; import { Get, IsmpRequest } from './types'; +import { encodePacked, keccak256, toHex } from 'viem'; +import { keccakAsHex } from '@polkadot/util-crypto'; async function ismpAddParachain(signer: KeyringPair, regionXApi: ApiPromise) { const addParaCall = regionXApi.tx.ismpParachain.addParachain([{ id: 1005, slotDuration: 6000 }]); @@ -44,8 +46,6 @@ async function makeIsmpResponse( StateProof: stateMachineProof, }); - // The issue is that requests are empty. That is why it is passing as well... - // At least we know handleUnsigned is handled successfully with zero requests. const response = [{ Response: { datagram: { @@ -60,27 +60,73 @@ async function makeIsmpResponse( context: request.get.context, timeoutTimestamp: request.get.timeout_timestamp, } - }], + }] }, proof: { height: { id: { - stateId: { - Kusama: 1005, - }, + stateId: { Kusama: 1005 }, consensusStateId: 'PAS0', }, - height: request.get.height.toString(), + height: request.get.height, }, proof: substrateStateProof.toHex(), }, signer: responderAddress, }, }]; - - console.log(response); + + // console.log(getRequestCommitment({ + // source: 'KUSAMA-2000', + // dest: 'KUSAMA-1005', + // nonce: request.get.nonce, + // from: request.get.from, + // keys: request.get.keys, + // height: request.get.height, + // context: request.get.context, + // timeoutTimestamp: request.get.timeout_timestamp, + // })); + + console.log(JSON.stringify(response)); await submitUnsigned(regionXApi.tx.ismp.handleUnsigned(response)); + await sleep(360 * 1000); +} + +export function getRequestCommitment(regionXApi: ApiPromise, get: any): string { + // const keysEncoding = "0x".concat(get.keys.map((key: string) => key.slice(2)).join("")) + // return keccak256( + // encodePacked( + // ["bytes", "bytes", "uint64", "uint64", "uint64", "bytes", "bytes", "bytes"], + // [ + // toHex(get.source), + // toHex(get.dest), + // get.nonce, + // get.height, + // get.timeoutTimestamp, + // get.from, + // keysEncoding as any, + // get.context, + // ], + // ), + // ) + const reqEnum = regionXApi.createType('Request', { + Get: { + source: get.source, // e.g. { Kusama: 1005 } + dest: get.dest, // e.g. { Kusama: 2000 } + nonce: get.nonce, // u64 + from: get.from, // Bytes + keys: get.keys, // Vec> + height: get.height, // u64 + timeout_timestamp: get.timeoutTimestamp, // u64 + } + }); + + const bytes = reqEnum.toU8a(); + + // ISMP uses keccak256 for request/response commitments + const commitment = keccakAsHex(bytes); + return commitment; } const isGetRequest = (request: IsmpRequest): request is { get: Get } => { diff --git a/e2e_tests/types.ts b/e2e_tests/types.ts index 99d895a2..f1da5709 100644 --- a/e2e_tests/types.ts +++ b/e2e_tests/types.ts @@ -62,8 +62,8 @@ export const REGIONX_API_TYPES = { }, Post: {}, Get: { - source: 'Text', - dest: 'Text', + source: 'StateMachine', + dest: 'StateMachine', nonce: 'u64', from: 'Vec', keys: 'Vec>', diff --git a/e2e_tests/xc-regions.common.ts b/e2e_tests/xc-regions.common.ts index f8e5006c..280dd493 100644 --- a/e2e_tests/xc-regions.common.ts +++ b/e2e_tests/xc-regions.common.ts @@ -87,10 +87,11 @@ async function transferRegionToRegionX( assert.equal((regions[0][1].toHuman() as any).owner, REGIONX_SOVEREIGN_ACCOUNT); // Respond to the ISMP get request: + console.log(region.record.Pending); const request = await queryRequest(regionXApi, region.record.Pending); await makeIsmpResponse(regionXApi, coretimeApi, request, encodeAddress(sender.address, 74)); - await sleep(360 * 1000); + // await sleep(360 * 1000); /* // The record should be set after ISMP response: diff --git a/e2e_tests/xc-transfer/region-transfer.ts b/e2e_tests/xc-transfer/region-transfer.ts index cc6764e1..3d4d5fd3 100644 --- a/e2e_tests/xc-transfer/region-transfer.ts +++ b/e2e_tests/xc-transfer/region-transfer.ts @@ -2,7 +2,7 @@ import { ApiPromise, Keyring, WsProvider } from '@polkadot/api'; import { openHrmpChannel, submitExtrinsic } from '../common'; import { UNIT } from '../consts'; import { configureBroker, purchaseRegion, startSales } from '../coretime.common'; -import { ismpAddParachain } from '../ismp.common'; +import { getRequestCommitment, ismpAddParachain } from '../ismp.common'; import { REGIONX_API_TYPES, REGIONX_CUSTOM_RPC } from '../types'; import { transferRegionToCoretimeChain, transferRegionToRegionX } from '../xc-regions.common'; @@ -25,6 +25,37 @@ async function run(_nodeName: any, networkInfo: any, _jsArgs: any) { const keyring = new Keyring({ type: 'sr25519' }); const alice = keyring.addFromUri('//Alice'); + // 0xb391a5b9a9fb2d4f6e26ede50664026ff64fd370e076048b77dfc9a2653f5082 + /* + [ + { + get: { + source: 'KUSAMA-2000', + dest: 'KUSAMA-1005', + nonce: 0, + from: '0x726567696f6e7370', + keys: [Array], + height: 27, + context: '0x', + timeout_timestamp: 0 + } + } + ] + */ + console.log(getRequestCommitment(regionXApi, { + source: {Kusama: 2000}, + dest: {Kusama: 1005}, + nonce: 0, + from: '0x726567696f6e7370', + keys: [ + '0x4dcb50595177a3177648411a42aca0f53dc63b0b76ffd6f80704a090da6f87197b8ad2503224d551cb1c49dc3958c83d200000000000ffffffffffffffffffff' + ], + height: 27, + context: '0x', + timeoutTimestamp: 0, + })); + /* + await submitExtrinsic( alice, relayApi.tx.balances.transferKeepAlive(PARA_2000_CHILD, 10n * UNIT), @@ -47,6 +78,7 @@ async function run(_nodeName: any, networkInfo: any, _jsArgs: any) { // Transferring back to the Coretime chain should work: // NOTE: the function contains checks, and if any of them fail, the test will fail. // await transferRegionToCoretimeChain(coretimeApi, regionXApi, alice, regionId); + */ } export { run }; diff --git a/package.json b/package.json index 6a1b15bc..78a2f11e 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,8 @@ "@polkadot/util": "^13.5.2", "@polkadot/util-crypto": "^13.5.2", "coretime-utils": "^0.3.2", - "typescript": "^4.1.6" + "scale-ts": "^1.6.1", + "viem": "^2.37.2" }, "devDependencies": { "@typescript-eslint/eslint-plugin": "^5.48.1", @@ -30,7 +31,6 @@ "eslint-import-resolver-typescript": "^3.5.3", "eslint-plugin-import": "^2.27.4", "eslint-plugin-prettier": "^4.0.0", - "prettier": "^2.8.1", - "prettier-plugin-organize-imports": "^3.2.0" + "prettier": "^2.8.1" } } diff --git a/runtime/kusama/src/ismp.rs b/runtime/kusama/src/ismp.rs index aa0bf3e9..d53c84a0 100644 --- a/runtime/kusama/src/ismp.rs +++ b/runtime/kusama/src/ismp.rs @@ -64,7 +64,6 @@ impl pallet_ismp::Config for Runtime { pub struct Router; impl IsmpRouter for Router { fn module_for_id(&self, id: Vec) -> Result, anyhow::Error> { - info!(target: "regionx::ismp", "Module_for_id: {:?}", id); let module = match ModuleId::from_bytes(&id) { Ok(pallet_regions::PALLET_ID) => Box::>::default(),