Skip to content

Commit bf8863a

Browse files
authored
adding in verification of stage 1 and mapping of rest of stages (#118)
* adding in verification of stage 1 and mapping of rest of stages * starting proof generation * constructing part 1 proof subxt issue * submiting big proof stage1 needs verification now * closer to generating stage 1 proof * can now match up roots but proof is not passing * made beefy map change to fix race issue with proof and root
1 parent 9840dda commit bf8863a

File tree

8 files changed

+794
-364
lines changed

8 files changed

+794
-364
lines changed

Cargo.lock

Lines changed: 373 additions & 341 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ parity-scale-codec = { version = "3.0.0", default-features = false, features = [
2121
parity-util-mem = "0.12.0"
2222
scale-info = { version = "2.2.0", default-features = false, features = ["derive"] }
2323
serde = "1.0"
24+
lazy_static = "1.4"
2425

2526
# Procedural macro dependencies
2627
proc-macro2 = "1.0.67"
@@ -87,8 +88,8 @@ sp-timestamp = { default_features = false, git = "https://github.com/coax1d/polk
8788
sp-transaction-pool = { default_features = false, git = "https://github.com/coax1d/polkadot-sdk", branch = "xcmp_customized_sdk" }
8889
sp-version = { default-features = false, git = "https://github.com/coax1d/polkadot-sdk", branch = "xcmp_customized_sdk" }
8990

90-
subxt = { git = 'https://github.com/paritytech/subxt', branch = "master" }
91-
subxt-signer = { git = 'https://github.com/paritytech/subxt', branch = "master", features = ["subxt"] }
91+
subxt = { git = 'https://github.com/paritytech/subxt', rev = "d44941fb1bdb1b46ef8537dd7511654facc3f763" }
92+
subxt-signer = { git = 'https://github.com/paritytech/subxt', rev = "d44941fb1bdb1b46ef8537dd7511654facc3f763", features = ["subxt"] }
9293

9394
# Node Deps
9495
frame-benchmarking-cli = { git = "https://github.com/coax1d/polkadot-sdk", branch = "xcmp_customized_sdk" }

pallets/xcmp_message_stuffer/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ sp-consensus-beefy = { workspace = true, default-features = false }
2525
sp-core = { workspace = true, default-features = false }
2626
sp-runtime = { workspace = true, default-features = false }
2727
sp-mmr-primitives = { workspace = true }
28+
sp-api = { workspace = true }
2829

2930
# Cumulus
3031
cumulus-primitives-core = { workspace = true, default-features = false }

pallets/xcmp_message_stuffer/src/lib.rs

Lines changed: 136 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ pub use pallet::*;
44
use pallet_mmr::{LeafDataProvider, ParentNumberAndHash, verify_leaves_proof};
55
use sp_consensus_beefy::mmr::MmrLeafVersion;
66

7-
use frame_support::{dispatch::{DispatchResult}, pallet_prelude::*,};
7+
use frame_support::{dispatch::{DispatchResult}, pallet_prelude::*, WeakBoundedVec};
88
use frame_system::pallet_prelude::*;
99
use cumulus_primitives_core::{ParaId, GetBeefyRoot};
1010
use sp_runtime::traits::{Hash as HashT, Keccak256};
@@ -34,6 +34,18 @@ type XcmpMessages<T, I> = <<T as crate::Config<I>>::XcmpDataProvider as XcmpMess
3434
type MmrProof = Proof<H256>;
3535
type LeafOf<T, I> = <crate::Pallet<T, I> as LeafDataProvider>::LeafData;
3636
type ChannelId = u64;
37+
type BinaryMerkleProof = ();
38+
39+
40+
#[derive(Debug, PartialEq, Eq, Clone, Encode, Decode, TypeInfo)]
41+
pub struct XcmpProof {
42+
// TODO: Probably should rename each of these stages to some fancy name
43+
// TODO: Remove tuples
44+
pub stage_1: (MmrProof, Vec<EncodableOpaqueLeaf>),
45+
pub stage_2: BinaryMerkleProof,
46+
pub stage_3: BinaryMerkleProof,
47+
pub stage_4: (MmrProof, Vec<EncodableOpaqueLeaf>),
48+
}
3749

3850
#[frame_support::pallet]
3951
pub mod pallet {
@@ -48,6 +60,7 @@ pub mod pallet {
4860
type RelayerOrigin: EnsureOrigin<Self::RuntimeOrigin>;
4961
/// This is used when updating the current `XcmpChannelRoots`
5062
type BeefyRootProvider: GetBeefyRoot;
63+
type MaxBeefyRootsKept: Get<u32>;
5164
}
5265

5366
#[pallet::pallet]
@@ -58,6 +71,14 @@ pub mod pallet {
5871
#[pallet::getter(fn xcmp_channel_roots)]
5972
pub type XcmpChannelRoots<T: Config<I>, I: 'static = ()> = StorageMap<_, Identity, ChannelId, H256, OptionQuery>;
6073

74+
#[pallet::storage]
75+
#[pallet::getter(fn seen_beefy_roots)]
76+
pub type SeenBeefyRoots<T: Config<I>, I: 'static = ()> = StorageMap<_, Identity, H256, BlockNumberFor<T>, OptionQuery>;
77+
78+
#[pallet::storage]
79+
#[pallet::getter(fn seen_beefy_roots_order)]
80+
pub type SeenBeefyRootsOrder<T: Config<I>, I: 'static = ()> = StorageValue<_, WeakBoundedVec<H256, T::MaxBeefyRootsKept>, ValueQuery>;
81+
6182
#[pallet::event]
6283
#[pallet::generate_deposit(pub(super) fn deposit_event)]
6384
pub enum Event<T: Config<I>, I: 'static = ()> {
@@ -77,13 +98,30 @@ pub mod pallet {
7798
XcmpProofAccepted,
7899
XcmpProofLeavesNotValid,
79100
XcmpNoChannelRootForChannelId,
101+
XcmpBeefyRootTargetedNeverSeen,
102+
}
103+
104+
#[pallet::hooks]
105+
impl<T: Config<I>, I: 'static> Hooks<BlockNumberFor<T>> for Pallet<T, I> {
106+
fn on_initialize(n: BlockNumberFor<T>) -> Weight {
107+
// TODO: Remove Temporary.. change from unwrapping default..
108+
let beefy_root = T::BeefyRootProvider::get_root().unwrap_or_default();
109+
SeenBeefyRoots::<T, I>::insert(&beefy_root.clone().into(), n);
110+
111+
let mut order = SeenBeefyRootsOrder::<T, I>::get().into_inner();
112+
order.push(beefy_root.into());
113+
114+
let item = WeakBoundedVec::force_from(order, None);
115+
SeenBeefyRootsOrder::<T, I>::put(item);
116+
117+
T::DbWeight::get().writes(3)
118+
}
80119
}
81120

82121
#[pallet::call]
83122
impl<T: Config<I>, I: 'static> Pallet<T, I> {
84123

85-
// TODO: Retrieve latest valid MmrChannelRoots from Relaychain (Perhaps this is done in on_initialize)
86-
124+
// TODO: This will
87125
#[pallet::call_index(0)]
88126
#[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))]
89127
pub fn submit_xcmp_proof(origin: OriginFor<T>, mmr_proof: MmrProof, leaves: Vec<EncodableOpaqueLeaf>, channel_id: u64) -> DispatchResult {
@@ -140,6 +178,101 @@ pub mod pallet {
140178
);
141179
Ok(())
142180
}
181+
182+
/// For now there is just one leaf in each membership proof
183+
/// TODO: Change to support multiple leaves..
184+
#[pallet::call_index(2)]
185+
#[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))]
186+
pub fn submit_big_proof(origin: OriginFor<T>, xcmp_proof: XcmpProof, beefy_root_targeted: H256) -> DispatchResult {
187+
ensure_signed(origin)?;
188+
189+
log::info!(
190+
target: LOG_TARGET,
191+
"Called submit big proof, targeting BEEFY_ROOT {:?}",
192+
beefy_root_targeted
193+
);
194+
195+
if !SeenBeefyRoots::<T, I>::contains_key(&beefy_root_targeted) {
196+
return Err(Error::<T, I>::XcmpBeefyRootTargetedNeverSeen.into())
197+
}
198+
199+
// Verify stage 1 via grabbing Beefy Root and checking against stage 1
200+
let (stage_1_proof, stage_1_leaves) = xcmp_proof.stage_1;
201+
202+
let nodes: Vec<_> = stage_1_leaves
203+
.clone()
204+
.into_iter()
205+
.map(|leaf|DataOrHash::<Keccak256, _>::Data(leaf.into_opaque_leaf()))
206+
.collect();
207+
208+
// TODO: Replace this error with an Error that specifies stage_1 of proof verification failed
209+
verify_leaves_proof(beefy_root_targeted.into(), nodes, stage_1_proof).map_err(|_| Error::<T, I>::XcmpProofNotValid)?;
210+
211+
log::info!(
212+
target: LOG_TARGET,
213+
"Verified Stage 1 Big XCMP Proof Successfully!!!",
214+
);
215+
216+
// Verify stage 2..
217+
// grab ParaHeader root from stage_1_proof
218+
// let para_header_root = Decode::decode(stage_1_leaves)
219+
// let (stage_2_proof, stage_2_leaves) = xcmp_proof.stage_2;
220+
221+
// These are different leaves they arent the MmrLeaves they are Binary Merkle Leaves
222+
// This will be a bit different but same rough idea as the Mmr
223+
// let nodes: Vec<_> = stage_2_leaves
224+
// .clone()
225+
// .into_iter()
226+
// .map(|leaf|DataOrHash::<Keccak256, _>::Data(leaf.into_opaque_leaf()))
227+
// .collect();
228+
229+
// binary merkle proof verification of para_header_root against stage_2_proof(leaves are (para_id, para_header))
230+
// verify_proof(root, nodes, stage_2_proof);
231+
232+
// let (para_id, para_header) = Decode::decode(stage_2_leaves);
233+
// Check channels storage to make sure this ParaId is someone that we support
234+
// if !XcmpChannels::<T>::exists(para_id) {
235+
// return Error::<T>::XcmpProofNoChannelWithSender
236+
// }
237+
238+
// Verify stage 3..
239+
// extract xcmp_root from paraheader..
240+
// let xcmp_root = extract(para_header)
241+
// let (stage_3_proof, stage_3_leaves) = xcmp_proof.stage_3;
242+
243+
// These are different leaves they arent the MmrLeaves they are Binary Merkle Leaves
244+
// This will be a bit different but same rough idea as the Mmr
245+
// let nodes: Vec<_> = stage_3_leaves
246+
// .clone()
247+
// .into_iter()
248+
// .map(|leaf|DataOrHash::<Keccak256, _>::Data(leaf.into_opaque_leaf()))
249+
// .collect();
250+
251+
// binary merkle proof verification of xcmp_root against stage_3_proof(mmr_root_from_sender)
252+
// verify_proof(xcmp_root, nodes, stage_3_proof)?;
253+
254+
// Verify stage 4..
255+
// let mmr_root = Decode::decode(stage_3_leaves);
256+
// let (stage_4_proof, stage_4_leaves) = xcmp_proof.stage_4;
257+
258+
// let nodes: Vec<_> = stage_4_leaves
259+
// .clone()
260+
// .into_iter()
261+
// .map(|leaf|DataOrHash::<Keccak256, _>::Data(leaf.into_opaque_leaf()))
262+
// .collect();
263+
264+
// TODO: Replace this error with an Error that specifies stage_4 of proof verification failed
265+
// verify_leaves_proof(mmr_root.into(), nodes, stage_4_proof).map_err(|_| Error::<T, I>::XcmpProofNotValid)?;
266+
267+
// Now process messages upstream
268+
// let xcmp_messages = Decode::decode(stage_4_leaves);
269+
// Send Xcmp Messages upstream to be decoded to XCM messages and processed
270+
// T::ProcessXcmpMessages(xcmp_messages);
271+
272+
// Log Event..
273+
274+
Ok(())
275+
}
143276
}
144277

145278
}

runtime/src/lib.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ mod weights;
1010
pub mod xcm_config;
1111

1212
use cumulus_primitives_core::{
13-
ParaId, CollectXcmpChannelMmrRoots,
13+
ParaId, CollectXcmpChannelMmrRoots, GetBeefyRoot
1414
};
1515
use sp_core::Hasher;
1616

@@ -523,6 +523,7 @@ parameter_types! {
523523
pub LeafVersion: MmrLeafVersion = MmrLeafVersion::new(0, 0);
524524

525525
pub ParaAIdentifier: ParaId = ParaId::from(1u32);
526+
pub MaxBeefyRootsKept: u32 = 64000u32;
526527
}
527528

528529
type ParaAChannel = pallet_xcmp_message_stuffer::Instance1;
@@ -533,6 +534,7 @@ impl pallet_xcmp_message_stuffer::Config<ParaAChannel> for Runtime {
533534
type XcmpDataProvider = XcmpDataProvider;
534535
type RelayerOrigin = EnsureRoot<AccountId>;
535536
type BeefyRootProvider = ParachainSystem;
537+
type MaxBeefyRootsKept = MaxBeefyRootsKept;
536538
}
537539

538540
type ParaAMmr = pallet_mmr::Instance1;
@@ -556,6 +558,7 @@ impl pallet_xcmp_message_stuffer::Config<ParaBChannel> for Runtime {
556558
type XcmpDataProvider = XcmpDataProvider;
557559
type RelayerOrigin = EnsureRoot<AccountId>;
558560
type BeefyRootProvider = ParachainSystem;
561+
type MaxBeefyRootsKept = MaxBeefyRootsKept;
559562
}
560563

561564
type ParaBMmr = pallet_mmr::Instance2;
@@ -724,6 +727,14 @@ impl_runtime_apis! {
724727
}
725728
}
726729

730+
impl cumulus_pallet_parachain_system::MessagingApi<Block, ParachainSystem> for Runtime {
731+
fn get_current_beefy_root() -> <ParachainSystem as GetBeefyRoot>::Root {
732+
// TODO: For now if there is no root just return H256::zero() Remove! for better error handling
733+
<ParachainSystem as GetBeefyRoot>::get_root().unwrap_or(
734+
sp_core::H256::from(&[1; 32]))
735+
}
736+
}
737+
727738
#[api_version(3)]
728739
impl mmr::MmrApi<Block, mmr::Hash, BlockNumber> for Runtime {
729740
fn mmr_root(mmr_id: u64) -> Result<mmr::Hash, mmr::Error> {

xcmp_relayer/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ license = "Apache-2.0"
77
description = "Relayer for XCMP"
88

99
[dependencies]
10-
runtime = { path = "../runtime", package = "parachain-template-runtime"}
10+
runtime = { path = "../runtime", package = "parachain-template-runtime" }
1111

1212
serde_json = { workspace = true }
1313
parity-scale-codec = { workspace = true }
@@ -20,6 +20,7 @@ directories = { workspace = true }
2020
futures = { workspace = true }
2121
env_logger = { workspace = true }
2222
log = { workspace = true }
23+
lazy_static = { workspace = true }
2324

2425
sp-runtime = { workspace = true }
2526
sp-core = { workspace = true }

0 commit comments

Comments
 (0)