Skip to content

Commit 7877f6c

Browse files
committed
define pallet mmr to provide leaf data and deposit log on new mmr root
1 parent 0aaffd9 commit 7877f6c

File tree

9 files changed

+182
-7
lines changed

9 files changed

+182
-7
lines changed

Cargo.lock

Lines changed: 18 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
[package]
2+
name = "pallet-subspace-mmr"
3+
homepage = "https://subspace.network"
4+
repository = "https://github.com/subspace/subspace"
5+
description = "Primitives for Subspace MMR"
6+
license = "GPL-3.0-or-later WITH Classpath-exception-2.0"
7+
version = "0.1.0"
8+
authors = ["Subspace Labs <https://subspace.network>"]
9+
edition = "2021"
10+
include = [
11+
"/src",
12+
"/Cargo.toml",
13+
]
14+
15+
[package.metadata.docs.rs]
16+
targets = ["x86_64-unknown-linux-gnu"]
17+
18+
[dependencies]
19+
codec = { package = "parity-scale-codec", version = "3.6.5", default-features = false, features = ["derive"] }
20+
frame-support = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "d6b500960579d73c43fc4ef550b703acfa61c4c8" }
21+
frame-system = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "d6b500960579d73c43fc4ef550b703acfa61c4c8" }
22+
log = { version = "0.4.20", default-features = false }
23+
scale-info = { version = "2.7.0", default-features = false, features = ["derive"] }
24+
sp-core = { version = "21.0.0", default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "d6b500960579d73c43fc4ef550b703acfa61c4c8" }
25+
sp-mmr-primitives = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "d6b500960579d73c43fc4ef550b703acfa61c4c8" }
26+
sp-runtime = { version = "24.0.0", default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "d6b500960579d73c43fc4ef550b703acfa61c4c8" }
27+
sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "d6b500960579d73c43fc4ef550b703acfa61c4c8" }
28+
sp-subspace-mmr = { version = "0.1.0", default-features = false, path = "../sp-subspace-mmr" }
29+
30+
[features]
31+
default = ["std"]
32+
std = [
33+
"codec/std",
34+
"frame-support/std",
35+
"frame-system/std",
36+
"log/std",
37+
"scale-info/std",
38+
"sp-core/std",
39+
"sp-mmr-primitives/std",
40+
"sp-runtime/std",
41+
"sp-std/std",
42+
"sp-subspace-mmr/std"
43+
]
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
// Copyright (C) 2022 Subspace Labs, Inc.
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 that provides necessary Leaf data for MMR.
17+
18+
#![cfg_attr(not(feature = "std"), no_std)]
19+
#![feature(associated_type_bounds)]
20+
21+
use frame_system::pallet_prelude::BlockNumberFor;
22+
use log::error;
23+
pub use pallet::*;
24+
use sp_mmr_primitives::{LeafDataProvider, OnNewRoot};
25+
use sp_runtime::traits::One;
26+
use sp_runtime::{DigestItem, Saturating};
27+
use sp_subspace_mmr::subspace_mmr_runtime_interface::get_mmr_leaf_data;
28+
use sp_subspace_mmr::{LeafDataV0, MmrDigest, MmrLeaf};
29+
30+
#[frame_support::pallet]
31+
mod pallet {
32+
use frame_support::Parameter;
33+
use sp_core::H256;
34+
35+
#[pallet::pallet]
36+
pub struct Pallet<T>(_);
37+
38+
#[pallet::config]
39+
pub trait Config: frame_system::Config<Hash: Into<H256> + From<H256>> {
40+
type MmrRootHash: Parameter + Copy;
41+
}
42+
}
43+
44+
impl<T: Config> OnNewRoot<T::MmrRootHash> for Pallet<T> {
45+
fn on_new_root(root: &T::MmrRootHash) {
46+
let digest = DigestItem::new_mmr_root(*root);
47+
<frame_system::Pallet<T>>::deposit_log(digest);
48+
}
49+
}
50+
51+
impl<T: Config> LeafDataProvider for Pallet<T> {
52+
type LeafData = MmrLeaf<BlockNumberFor<T>, T::Hash>;
53+
54+
fn leaf_data() -> Self::LeafData {
55+
let block_number = frame_system::Pallet::<T>::block_number().saturating_sub(One::one());
56+
let block_hash = frame_system::Pallet::<T>::parent_hash();
57+
// unfortunately, we Leaf data provider trait expects the impl to be infallible
58+
// but our host function might fail for any reason but practically shouldn't since
59+
// we are querying the immediate parent block
60+
// We will just log an error in case of such ever happening
61+
let leaf_data = get_mmr_leaf_data(block_hash.into()).unwrap_or_else(|| {
62+
error!(target: "runtime::subspace_mmr", "Failed to fetch leaf data for Block hash{block_hash:?}");
63+
Default::default()
64+
});
65+
MmrLeaf::V0(LeafDataV0 {
66+
block_number,
67+
block_hash,
68+
state_root: leaf_data.state_root.into(),
69+
extrinsics_root: leaf_data.extrinsics_root.into(),
70+
})
71+
}
72+
}

crates/sp-subspace-mmr/src/lib.rs

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,15 @@
1919

2020
#[cfg(feature = "std")]
2121
pub mod host_functions;
22-
pub mod runtime_interface;
22+
mod runtime_interface;
23+
pub use runtime_interface::subspace_mmr_runtime_interface;
2324
#[cfg(feature = "std")]
2425
pub use runtime_interface::subspace_mmr_runtime_interface::HostFunctions;
2526

26-
use codec::{Decode, Encode};
27+
use codec::{Codec, Decode, Encode};
2728
use scale_info::TypeInfo;
29+
use sp_runtime::generic::OpaqueDigestItemId;
30+
use sp_runtime::DigestItem;
2831

2932
/// MMR leaf structure
3033
#[derive(Debug, Decode, Encode, TypeInfo, PartialEq, Eq, Clone)]
@@ -43,3 +46,28 @@ pub struct LeafDataV0<BlockNumber, Hash> {
4346
/// Can be used to prove block body
4447
pub extrinsics_root: Hash,
4548
}
49+
50+
/// MMR specific digest item.
51+
#[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo)]
52+
pub enum MmrDigestItem<MmrRootHash: Codec> {
53+
NewMmrRoot(MmrRootHash),
54+
}
55+
56+
/// MMR specific digest items interface.
57+
pub trait MmrDigest<MmrRootHash> {
58+
fn new_mmr_root(root: MmrRootHash) -> Self;
59+
fn as_new_mmr_root(&self) -> Option<MmrRootHash>;
60+
}
61+
62+
impl<MmrRootHash: Codec> MmrDigest<MmrRootHash> for DigestItem {
63+
fn new_mmr_root(root: MmrRootHash) -> Self {
64+
DigestItem::Other(MmrDigestItem::NewMmrRoot(root).encode())
65+
}
66+
67+
fn as_new_mmr_root(&self) -> Option<MmrRootHash> {
68+
match self.try_to::<MmrDigestItem<MmrRootHash>>(OpaqueDigestItemId::Other) {
69+
Some(MmrDigestItem::NewMmrRoot(root)) => Some(root),
70+
_ => None,
71+
}
72+
}
73+
}

crates/sp-subspace-mmr/src/runtime_interface.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ pub trait SubspaceMmrRuntimeInterface {
2020
}
2121

2222
/// Leaf data sent back from host function.
23-
#[derive(Debug, Decode, Encode, TypeInfo, PartialEq, Eq, Clone)]
23+
#[derive(Debug, Decode, Encode, TypeInfo, PartialEq, Eq, Clone, Default)]
2424
pub struct LeafData {
2525
pub state_root: H256,
2626
pub extrinsics_root: H256,

crates/subspace-runtime/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ pallet-offences-subspace = { version = "0.1.0", default-features = false, path =
3333
pallet-rewards = { version = "0.1.0", default-features = false, path = "../pallet-rewards" }
3434
pallet-runtime-configs = { version = "0.1.0", default-features = false, path = "../pallet-runtime-configs" }
3535
pallet-subspace = { version = "0.1.0", default-features = false, features = ["serde"], path = "../pallet-subspace" }
36+
pallet-subspace-mmr = { version = "0.1.0", default-features = false, path = "../pallet-subspace-mmr" }
3637
pallet-sudo = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "d6b500960579d73c43fc4ef550b703acfa61c4c8" }
3738
pallet-timestamp = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "d6b500960579d73c43fc4ef550b703acfa61c4c8" }
3839
pallet-transaction-fees = { version = "0.1.0", default-features = false, path = "../pallet-transaction-fees" }
@@ -90,6 +91,7 @@ std = [
9091
"pallet-rewards/std",
9192
"pallet-runtime-configs/std",
9293
"pallet-subspace/std",
94+
"pallet-subspace-mmr/std",
9395
"pallet-sudo/std",
9496
"pallet-timestamp/std",
9597
"pallet-transaction-fees/std",

crates/subspace-runtime/src/lib.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -667,11 +667,15 @@ mod mmr {
667667
impl pallet_mmr::Config for Runtime {
668668
const INDEXING_PREFIX: &'static [u8] = mmr::INDEXING_PREFIX;
669669
type Hashing = Keccak256;
670-
type LeafData = pallet_mmr::ParentNumberAndHash<Runtime>;
671-
type OnNewRoot = ();
670+
type LeafData = SubspaceMmr;
671+
type OnNewRoot = SubspaceMmr;
672672
type WeightInfo = ();
673673
}
674674

675+
impl pallet_subspace_mmr::Config for Runtime {
676+
type MmrRootHash = mmr::Hash;
677+
}
678+
675679
construct_runtime!(
676680
pub struct Runtime {
677681
System: frame_system = 0,
@@ -692,6 +696,7 @@ construct_runtime!(
692696
Vesting: orml_vesting = 13,
693697

694698
Mmr: pallet_mmr = 30,
699+
SubspaceMmr: pallet_subspace_mmr = 31,
695700

696701
// messenger stuff
697702
// Note: Indexes should match with indexes on other chains and domains

test/subspace-test-runtime/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ pallet-mmr = { version = "4.0.0-dev", default-features = false, git = "https://g
2929
pallet-offences-subspace = { version = "0.1.0", default-features = false, path = "../../crates/pallet-offences-subspace" }
3030
pallet-rewards = { version = "0.1.0", default-features = false, path = "../../crates/pallet-rewards" }
3131
pallet-subspace = { version = "0.1.0", default-features = false, features = ["serde"], path = "../../crates/pallet-subspace" }
32+
pallet-subspace-mmr = { version = "0.1.0", default-features = false, path = "../../crates/pallet-subspace-mmr" }
3233
pallet-sudo = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "d6b500960579d73c43fc4ef550b703acfa61c4c8" }
3334
pallet-timestamp = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "d6b500960579d73c43fc4ef550b703acfa61c4c8" }
3435
pallet-transaction-fees = { version = "0.1.0", default-features = false, path = "../../crates/pallet-transaction-fees" }
@@ -81,6 +82,7 @@ std = [
8182
"pallet-offences-subspace/std",
8283
"pallet-rewards/std",
8384
"pallet-subspace/std",
85+
"pallet-subspace-mmr/std",
8486
"pallet-sudo/std",
8587
"pallet-timestamp/std",
8688
"pallet-transaction-fees/std",

test/subspace-test-runtime/src/lib.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -703,11 +703,15 @@ mod mmr {
703703
impl pallet_mmr::Config for Runtime {
704704
const INDEXING_PREFIX: &'static [u8] = mmr::INDEXING_PREFIX;
705705
type Hashing = Keccak256;
706-
type LeafData = pallet_mmr::ParentNumberAndHash<Runtime>;
707-
type OnNewRoot = ();
706+
type LeafData = SubspaceMmr;
707+
type OnNewRoot = SubspaceMmr;
708708
type WeightInfo = ();
709709
}
710710

711+
impl pallet_subspace_mmr::Config for Runtime {
712+
type MmrRootHash = mmr::Hash;
713+
}
714+
711715
construct_runtime!(
712716
pub struct Runtime {
713717
System: frame_system = 0,
@@ -727,6 +731,7 @@ construct_runtime!(
727731
Vesting: orml_vesting = 7,
728732

729733
Mmr: pallet_mmr = 30,
734+
SubspaceMmr: pallet_subspace_mmr = 31,
730735

731736
// messenger stuff
732737
// Note: Indexes should match with indexes on other chains and domains

0 commit comments

Comments
 (0)