Skip to content

Commit

Permalink
Generating full xcmp proof (#132)
Browse files Browse the repository at this point in the history
* comment for generating stage2

* Adding ability to grab ParaMerkleProof.. wasm trap error..

* fixing bug with paraId

* fixing proof generation

* small refactorings

* got stage4 and stage 3 proof generation setup

* adding small func and test for digest

* generating correct full proof

* final cleanup
  • Loading branch information
coax1d authored Mar 19, 2024
1 parent a994956 commit 9a682b1
Show file tree
Hide file tree
Showing 5 changed files with 458 additions and 121 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

35 changes: 32 additions & 3 deletions pallets/xcmp_message_stuffer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,19 +31,39 @@ pub trait XcmpMessageProvider<Hash> {
fn get_xcmp_messages(block_hash: Hash, para_id: ParaId) -> Self::XcmpMessages;
}

#[derive(Debug, PartialEq, Eq, Clone, Encode, Decode, TypeInfo)]
pub struct ChannelMerkleProof {
pub root: H256,
pub proof: Vec<H256>,
pub num_leaves: u64,
pub leaf_index: u64,
pub leaf: H256,
}

impl Default for ChannelMerkleProof {
fn default() -> Self {
ChannelMerkleProof {
root: H256::zero(),
proof: Vec::new(),
num_leaves: 0u64,
leaf_index: 0u64,
leaf: H256::zero(),
}
}
}

type XcmpMessages<T, I> = <<T as crate::Config<I>>::XcmpDataProvider as XcmpMessageProvider<<T as frame_system::Config>::Hash>>::XcmpMessages;
type MmrProof = Proof<H256>;
type ChannelId = u64;
type BinaryMerkleProof = ();


#[derive(Debug, PartialEq, Eq, Clone, Encode, Decode, TypeInfo)]
pub struct XcmpProof {
// TODO: Probably should rename each of these stages to some fancy name
// TODO: Remove tuples
pub stage_1: (MmrProof, Vec<EncodableOpaqueLeaf>),
pub stage_2: ParaMerkleProof,
pub stage_3: BinaryMerkleProof,
pub stage_3: ChannelMerkleProof,
pub stage_4: (MmrProof, Vec<EncodableOpaqueLeaf>),
}

Expand Down Expand Up @@ -121,7 +141,6 @@ pub mod pallet {
#[pallet::call]
impl<T: Config<I>, I: 'static> Pallet<T, I> {

// TODO: This will
#[pallet::call_index(0)]
#[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))]
pub fn submit_test_proof(origin: OriginFor<T>, mmr_proof: MmrProof, leaves: Vec<EncodableOpaqueLeaf>, channel_id: u64) -> DispatchResult {
Expand Down Expand Up @@ -216,6 +235,7 @@ pub mod pallet {
// Verify stage 2..
// grab ParaHeader root from stage_1_proof
// let para_header_root = Decode::decode(stage_1_leaves)
// Take Last leaf element as the para_header_root selected
// let (stage_2_proof, stage_2_leaves) = xcmp_proof.stage_2;

// These are different leaves they arent the MmrLeaves they are Binary Merkle Leaves
Expand Down Expand Up @@ -306,4 +326,13 @@ impl<T: Config<I>, I: 'static> LeafDataProvider for Pallet<T, I> {
parent_number_and_hash: ParentNumberAndHash::<T>::leaf_data(),
}
}
}

sp_api::decl_runtime_apis! {
/// API useful for BEEFY light clients.
pub trait ChannelMerkleApi
{
/// Return BinaryMerkle Proof for a particular parachains inclusion in ParaHeader tree
fn get_xcmp_channels_proof(channel_id: u64) -> Option<ChannelMerkleProof>;
}
}
32 changes: 31 additions & 1 deletion runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ use sp_runtime::{

use sp_consensus_beefy::mmr::MmrLeafVersion;

use parity_scale_codec::Encode;
use parity_scale_codec::{Encode, Decode};

use polkadot_runtime_parachains::paras::{ParaMerkleProof, ParaLeaf};

use sp_std::prelude::*;
#[cfg(feature = "std")]
Expand Down Expand Up @@ -505,6 +507,28 @@ impl CollectXcmpChannelMmrRoots for XcmpChannelRootCollector {
}
}

use pallet_xcmp_message_stuffer::ChannelMerkleProof;
pub struct ChannelMerkleProofGen;
impl ChannelMerkleProofGen {
// TODO: Allow the channel_id to select the appropriate MMR and index of leaf
pub fn gen_merkle_proof(_channel_id: u64) -> Option<ChannelMerkleProof> {
let index_to_prove = 0;

let merkle_proof = binary_merkle_tree::merkle_proof::<mmr::Hashing, _, sp_core::H256>(
vec![MmrParaA::mmr_root_hash(), MmrParaB::mmr_root_hash()],
index_to_prove
);
let result_proof = ChannelMerkleProof {
root: merkle_proof.root,
proof: merkle_proof.proof,
num_leaves: merkle_proof.number_of_leaves as u64,
leaf_index: merkle_proof.leaf_index as u64,
leaf: merkle_proof.leaf,
};
Some(result_proof)
}
}


parameter_types! {
/// Version of the produced MMR leaf.
Expand Down Expand Up @@ -735,6 +759,12 @@ impl_runtime_apis! {
}
}

impl pallet_xcmp_message_stuffer::ChannelMerkleApi<Block> for Runtime {
fn get_xcmp_channels_proof(channel_id: u64) -> Option<ChannelMerkleProof> {
ChannelMerkleProofGen::gen_merkle_proof(channel_id)
}
}

#[api_version(3)]
impl mmr::MmrApi<Block, mmr::Hash, BlockNumber> for Runtime {
fn mmr_root(mmr_id: u64) -> Result<mmr::Hash, mmr::Error> {
Expand Down
2 changes: 2 additions & 0 deletions xcmp_relayer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ runtime = { path = "../runtime", package = "parachain-template-runtime" }

polkadot-runtime-parachains = { workspace = true }
polkadot-parachain = { workspace = true }
cumulus-primitives-core = { workspace = true }
serde_json = { workspace = true }
parity-scale-codec = { workspace = true }
jsonrpsee = { workspace = true }
Expand All @@ -27,6 +28,7 @@ lazy_static = { workspace = true }
sp-runtime = { workspace = true }
sp-core = { workspace = true }
sp-mmr-primitives = { workspace = true }
sp-consensus-beefy = { workspace = true }

subxt = { workspace = true }
subxt-signer = { workspace = true }
Expand Down
Loading

0 comments on commit 9a682b1

Please sign in to comment.